Advertisement
PIBogdanov

MenuCPP

Jun 30th, 2023
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.41 KB | None | 0 0
  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <string>
  4. #include <cstddef>
  5. #include <thread>
  6. #include <chrono>
  7.  
  8. const size_t escapeKey = 27; // Escape key
  9.  
  10. #ifdef _WIN32 // Windows-specific code
  11.  
  12. #include <Windows.h>
  13. #include <conio.h>
  14.  
  15. const size_t upArrow = 72; // Up arrow key (Windows)
  16.  
  17. const size_t downArrow = 80; // Down arrow key (Windows)
  18.  
  19. const size_t enterKey = 13; // Enter key (Windows)
  20.  
  21. void ClearScreen()
  22. {
  23.     std::system("cls");
  24. }
  25.  
  26. HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  27.  
  28. void FontSize(SHORT sizeOfTheFont)
  29. {
  30.     CONSOLE_FONT_INFOEX fontInfo{};
  31.  
  32.     fontInfo.cbSize = sizeof(fontInfo);
  33.  
  34.     if (!GetCurrentConsoleFontEx(consoleHandle, FALSE, &fontInfo))
  35.     {
  36.         // Handle error: unable to retrieve font info
  37.         // You can print an error message or throw an exception
  38.  
  39.         return;
  40.     }
  41.  
  42.     fontInfo.dwFontSize.X += sizeOfTheFont; // Increase the font width
  43.  
  44.     fontInfo.dwFontSize.Y += sizeOfTheFont; // Increase the font height
  45.  
  46.     if (!SetCurrentConsoleFontEx(consoleHandle, FALSE, &fontInfo))
  47.     {
  48.         // Handle error: unable to set font info
  49.         // You can print an error message or throw an exception
  50.  
  51.         return;
  52.     }
  53. }
  54.  
  55. HWND consoleWindowHandle = GetConsoleWindow(); // Get the console window handle
  56.  
  57. void MaximizeWindow()
  58. {
  59.     ShowWindow(consoleWindowHandle, SW_MAXIMIZE); // Maximize the window
  60. }
  61.  
  62. void ShowConsoleCursor(bool showFlag)
  63. {
  64.     CONSOLE_CURSOR_INFO cursorInfo;
  65.  
  66.     if (!GetConsoleCursorInfo(consoleHandle, &cursorInfo))
  67.     {
  68.         // Handle error: unable to retrieve cursor info
  69.         // You can print an error message or throw an exception
  70.  
  71.         return;
  72.     }
  73.  
  74.     cursorInfo.bVisible = showFlag; // Sets the cursor visibility
  75.  
  76.     if (!SetConsoleCursorInfo(consoleHandle, &cursorInfo))
  77.     {
  78.         // Handle error: unable to set cursor info
  79.         // You can print an error message or throw an exception
  80.  
  81.         return;
  82.     }
  83. }
  84.  
  85. SHORT GetConsoleSizes()
  86. {
  87.     CONSOLE_SCREEN_BUFFER_INFO screenInfo;
  88.  
  89.     if (!GetConsoleScreenBufferInfo(consoleHandle, &screenInfo))
  90.     {
  91.         // Handle error: unable to retrieve font info
  92.         // You can print an error message or throw an exception
  93.  
  94.         return false;
  95.     }
  96.  
  97.     return screenInfo.dwSize.X;
  98. }
  99.  
  100. int KeyboardInput()
  101. {
  102.     return _getch();;
  103. }
  104.  
  105. #else // Unix/Linux/MacOS-specific code
  106.  
  107. #include <sys/ioctl.h>
  108. #include <unistd.h>
  109. #include <termios.h>
  110. #include <X11/Xlib.h>
  111.  
  112. const size_t upArrow = 65; // Up arrow key (Linux/MacOS)
  113.  
  114. const size_t downArrow = 66; // Down arrow key (Linux/MacOS)
  115.  
  116. const size_t enterKey = 10; // Enter key (Linux/MacOS)
  117.  
  118. void ClearScreen()
  119. {
  120.     std::system("clear");
  121. }
  122.  
  123. void FontSize(short sizeOfTheFont)
  124. {
  125.     struct winsize ws;
  126.  
  127.     if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1)
  128.     {
  129.         // Handle error: unable to retrieve terminal size
  130.         // You can print an error message or throw an exception
  131.  
  132.         return;
  133.     }
  134.  
  135.     // Increase the font size by modifying the terminal size
  136.     ws.ws_row += sizeOfTheFont; // Increase the number of rows
  137.  
  138.     ws.ws_col += sizeOfTheFont; // Increase the number of columns
  139.  
  140.     if (ioctl(STDOUT_FILENO, TIOCSWINSZ, &ws) == -1)
  141.     {
  142.         // Handle error: unable to set terminal size
  143.         // You can print an error message or throw an exception
  144.  
  145.         return;
  146.     }
  147. }
  148.  
  149. void MaximizeWindow()
  150. {
  151.     struct winsize ws;
  152.  
  153.     ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
  154.  
  155.     std::cout << "\e[8;" << ws.ws_row << ";" << ws.ws_col << "t";  // Set terminal size
  156. }
  157.  
  158. void ShowConsoleCursor(bool showFlag)
  159. {
  160.     std::cout << (showFlag ? "\033[?25h" : "\033[?25l"); // show/hide cursor
  161.  
  162.     std::cout.flush();
  163. }
  164.  
  165. short GetConsoleSizes()
  166. {
  167.     struct winsize ws;
  168.  
  169.     if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1)
  170.     {
  171.         // Handle error: unable to retrieve terminal size
  172.         // You can print an error message or throw an exception
  173.  
  174.         std::exit(0);
  175.     }
  176.  
  177.     return ws.ws_col;
  178. }
  179.  
  180. int KeyboardInput()
  181. {
  182.     struct termios oldSettings, newSettings;
  183.  
  184.     // Get the current terminal settings
  185.     tcgetattr(STDIN_FILENO, &oldSettings);
  186.  
  187.     // Copy the current settings to the new settings
  188.     newSettings = oldSettings;
  189.  
  190.     // Disable canonical mode (line buffering) and input echo
  191.     newSettings.c_lflag &= ~(ICANON | ECHO);
  192.  
  193.     // Apply the new terminal settings
  194.     tcsetattr(STDIN_FILENO, TCSANOW, &newSettings);
  195.  
  196.     // Read a single character
  197.     char character = getchar();
  198.  
  199.     // Restore the original terminal settings
  200.     tcsetattr(STDIN_FILENO, TCSANOW, &oldSettings);
  201.  
  202.     return character;
  203. }
  204.  
  205. #endif
  206.  
  207. template <typename T>
  208.  
  209. void MainMenu(T[], size_t, std::string[], size_t, std::string&, int);
  210.  
  211. void DisplayMenu(std::string[], size_t, std::string&, const size_t&);
  212.  
  213. template <typename T>
  214.  
  215. int MenuMovement(T[], int, size_t, int);
  216.  
  217. void GameStart(int);
  218.  
  219. void Controls(int);
  220.  
  221. void Credits(int);
  222.  
  223. void ExitGame(int);
  224.  
  225. bool IsKeyPressedToGoBackToThePreviousMenu(int);
  226.  
  227. template <typename T>
  228.  
  229. void DifficultyMenu(T[], size_t, std::string[], size_t, std::string&, int);
  230.  
  231. void CoutCentered(const std::string&);
  232.  
  233. int main()
  234. {
  235.     FontSize(6);
  236.  
  237.     MaximizeWindow();
  238.  
  239.     ShowConsoleCursor(false);
  240.  
  241.     typedef void(*menuOptions)(int);
  242.  
  243.     menuOptions mainMenuOptions[] = { GameStart, Controls, Credits, ExitGame };
  244.  
  245.     size_t sizeOfTheArray = sizeof(mainMenuOptions) / sizeof(mainMenuOptions[0]);
  246.  
  247.     std::string mainMenu[] = { "Start Game", "Controls", "Credits", "Exit" };
  248.  
  249.     size_t sizeOfTheStringMenu = std::size(mainMenu);
  250.  
  251.     std::string text = "Main Menu";
  252.  
  253.     MainMenu(mainMenuOptions, sizeOfTheArray, mainMenu, sizeOfTheStringMenu, text, 0);
  254.  
  255.     return 0;
  256. }
  257.  
  258. template <typename T>
  259.  
  260. void MainMenu(T mainMenuOptions[], size_t sizeOfTheArray, std::string mainMenu[], size_t sizeOfTheStringMenu, std::string& text, int selectedOption)
  261. {
  262.     int key = 0;
  263.  
  264.     int previousSelectedOption = 0;
  265.  
  266.     while (true)
  267.     {
  268.         DisplayMenu(mainMenu, sizeOfTheStringMenu, text, selectedOption);
  269.  
  270.         previousSelectedOption = selectedOption;
  271.  
  272.         selectedOption = MenuMovement(mainMenuOptions, selectedOption, sizeOfTheArray, key);
  273.  
  274.         if (selectedOption < 0)
  275.         {
  276.             selectedOption = previousSelectedOption;
  277.         }
  278.  
  279.         std::this_thread::sleep_for(std::chrono::milliseconds(12));
  280.     }
  281. }
  282.  
  283. void DisplayMenu(std::string mainMenu[], size_t sizeOfTheStringMenu, std::string& text, const size_t& selectedOption)
  284. {
  285.     ClearScreen();
  286.  
  287.     std::cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  288.  
  289.     CoutCentered(text);
  290.  
  291.     std::cout << "\n" << "\n" << "\n";
  292.  
  293.     for (size_t i = 0; i < sizeOfTheStringMenu; i++)
  294.     {
  295.         selectedOption == i ? CoutCentered("--> " + mainMenu[i]) : CoutCentered("" + mainMenu[i]);
  296.  
  297.         if (i < sizeOfTheStringMenu - 1)
  298.         {
  299.             std::cout << "\n";
  300.         }
  301.     }
  302. }
  303.  
  304. /*
  305. This function is "int" and not "size_t", because the "size_t" data type doesn't return negative numbers,
  306. it returns only numbers from 0 to 18 446 744 073 709 551 615 or 18_446_744_073_709_551_615 (the same number),
  307. in other words, only positive, including 0
  308. */
  309.  
  310. template <typename T>
  311.  
  312. int MenuMovement(T menu[], int selectedOption, size_t sizeOfTheArray, int key)
  313. {
  314.     key = KeyboardInput();
  315.  
  316.     if (key == upArrow)
  317.     {
  318.         selectedOption--;
  319.  
  320.         if (selectedOption < 0)
  321.         {
  322.             selectedOption = sizeOfTheArray - 1;
  323.         }
  324.     }
  325.  
  326.     else if (key == downArrow)
  327.     {
  328.         selectedOption++;
  329.  
  330.         if (selectedOption >= sizeOfTheArray)
  331.         {
  332.             selectedOption = 0;
  333.         }
  334.     }
  335.  
  336.     else if (key == enterKey)
  337.     {
  338.         menu[selectedOption](selectedOption);
  339.     }
  340.  
  341.     else if (key == escapeKey)
  342.     {
  343.         selectedOption = - 6;
  344.     }
  345.  
  346.     return selectedOption;
  347. }
  348.  
  349. void GameStart(int selectedOption)
  350. {
  351.     ClearScreen();
  352.  
  353.     std::cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  354.  
  355.     typedef void(*difficultyOptions)(int);
  356.  
  357.     difficultyOptions difficultyMenuOptions[] = { GameStart, Credits, ExitGame };
  358.  
  359.     size_t sizeOfTheArray = sizeof(difficultyMenuOptions) / sizeof(difficultyMenuOptions[0]);
  360.  
  361.     std::string difficultyMenu[] = { "Start", "Cdits", "Eit" };
  362.  
  363.     size_t sizeOfTheStringMenu = std::size(difficultyMenu);
  364.  
  365.     std::string text = "Difficulty Menu";
  366.  
  367.     DifficultyMenu(difficultyMenuOptions, sizeOfTheArray, difficultyMenu, sizeOfTheStringMenu, text, selectedOption);
  368. }
  369.  
  370. void Controls(int selectedOption)
  371. {
  372.     ClearScreen();
  373.  
  374.     std::cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  375.  
  376.     CoutCentered("The controls are showed!");
  377.  
  378.     while (!IsKeyPressedToGoBackToThePreviousMenu(KeyboardInput()));
  379. }
  380.  
  381. void Credits(int selectedOption)
  382. {
  383.     ClearScreen();
  384.  
  385.     std::cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  386.  
  387.     CoutCentered("The credits are showed!");
  388.  
  389.     while (!IsKeyPressedToGoBackToThePreviousMenu(KeyboardInput()));
  390. }
  391.  
  392. void ExitGame(int selectedOption)
  393. {
  394.     std::exit(0);
  395. }
  396.  
  397. bool IsKeyPressedToGoBackToThePreviousMenu(int key)
  398. {
  399.     if (key == escapeKey)
  400.     {
  401.         return true;
  402.     }
  403.  
  404.     return false;
  405. }
  406.  
  407. template <typename T>
  408.  
  409. void DifficultyMenu(T difficultyMenuOptions[], size_t sizeOfTheArray, std::string difficultyMenu[], size_t sizeOfTheStringMenu, std::string& text, int selectedOption)
  410. {
  411.     int key = 0;
  412.  
  413.     while (selectedOption != -6)
  414.     {
  415.         DisplayMenu(difficultyMenu, sizeOfTheStringMenu, text, selectedOption);
  416.  
  417.         selectedOption = MenuMovement(difficultyMenuOptions, selectedOption, sizeOfTheArray, key);
  418.  
  419.         std::this_thread::sleep_for(std::chrono::milliseconds(12));
  420.     }
  421. }
  422.  
  423. void CoutCentered(const std::string& text)
  424. {
  425.     size_t textWidth = text.length();
  426.  
  427.     short consoleWidth = GetConsoleSizes();
  428.  
  429.     size_t leftMargin = (consoleWidth - textWidth) / 2;
  430.  
  431.     std::cout.width(leftMargin + textWidth);
  432.  
  433.     std::cout << text;
  434. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement