Advertisement
PIBogdanov

MenuCPP

Jun 30th, 2023
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.36 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 <X11/Xlib.h>
  110.  
  111. const size_t upArrow = 65; // Up arrow key (Linux/MacOS)
  112.  
  113. const size_t downArrow = 66; // Down arrow key (Linux/MacOS)
  114.  
  115. const size_t enterKey = 10; // Enter key (Linux/MacOS)
  116.  
  117. void ClearScreen()
  118. {
  119.     std::system("clear");
  120. }
  121.  
  122. void FontSize(short sizeOfTheFont)
  123. {
  124.     struct winsize ws;
  125.  
  126.     if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1)
  127.     {
  128.         // Handle error: unable to retrieve terminal size
  129.         // You can print an error message or throw an exception
  130.  
  131.         return;
  132.     }
  133.  
  134.     // Increase the font size by modifying the terminal size
  135.     ws.ws_row += sizeOfTheFont; // Increase the number of rows
  136.  
  137.     ws.ws_col += sizeOfTheFont; // Increase the number of columns
  138.  
  139.     if (ioctl(STDOUT_FILENO, TIOCSWINSZ, &ws) == -1)
  140.     {
  141.         // Handle error: unable to set terminal size
  142.         // You can print an error message or throw an exception
  143.  
  144.         return;
  145.     }
  146. }
  147.  
  148. void MaximizeWindow()
  149. {
  150.     // Open a connection to the X server
  151.     Display* display = XOpenDisplay(NULL);
  152.  
  153.     // Get the default screen of the X server
  154.     Screen* screen = DefaultScreenOfDisplay(display);
  155.  
  156.     // Get the root window of the default screen
  157.     Window rootWindow = RootWindow(display, XScreenNumberOfScreen(screen));
  158.  
  159.     // Get the width and height of the screen
  160.     int screenWidth = XWidthOfScreen(screen);
  161.     int screenHeight = XHeightOfScreen(screen);
  162.  
  163.     // Create a new window covering the entire screen
  164.     Window window = XCreateSimpleWindow(display, rootWindow, 0, 0, screenWidth, screenHeight, 0, 0, 0);
  165.  
  166.     // Map the window to make it visible
  167.     XMapWindow(display, window);
  168.  
  169.     // Set the input focus to the new window
  170.     XSetInputFocus(display, window, RevertToPointerRoot, CurrentTime);
  171.  
  172.     // Grab the keyboard and mouse events to prevent input from reaching other windows
  173.     XGrabKeyboard(display, window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
  174.     XGrabPointer(display, window, True, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
  175. }
  176.  
  177. void ShowConsoleCursor(bool showFlag)
  178. {
  179.     std::cout << (showFlag ? "\033[?25h" : "\033[?25l"); // show/hide cursor
  180.  
  181.     std::cout.flush();
  182. }
  183.  
  184. short GetConsoleSizes()
  185. {
  186.     struct winsize ws;
  187.  
  188.     if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1)
  189.     {
  190.         // Handle error: unable to retrieve terminal size
  191.         // You can print an error message or throw an exception
  192.  
  193.         std::exit(0);
  194.     }
  195.  
  196.     return ws.ws_col;
  197. }
  198.  
  199. int KeyboardInput()
  200. {
  201.     struct termios oldSettings, newSettings;
  202.  
  203.     // Get the current terminal settings
  204.     tcgetattr(STDIN_FILENO, &oldSettings);
  205.  
  206.     // Copy the current settings to the new settings
  207.     newSettings = oldSettings;
  208.  
  209.     // Disable canonical mode (line buffering) and input echo
  210.     newSettings.c_lflag &= ~(ICANON | ECHO);
  211.  
  212.     // Apply the new terminal settings
  213.     tcsetattr(STDIN_FILENO, TCSANOW, &newSettings);
  214.  
  215.     // Read a single character
  216.     char character = getchar();
  217.  
  218.     // Restore the original terminal settings
  219.     tcsetattr(STDIN_FILENO, TCSANOW, &oldSettings);
  220.  
  221.     return character;
  222. }
  223.  
  224. #endif
  225.  
  226. template <typename T>
  227.  
  228. void MainMenu(T[], size_t, std::string[], size_t, std::string&, int);
  229.  
  230. void DisplayMenu(std::string[], size_t, std::string&, const size_t&);
  231.  
  232. template <typename T>
  233.  
  234. int MenuMovement(T[], int, size_t, int);
  235.  
  236. void GameStart(int);
  237.  
  238. void Controls(int);
  239.  
  240. void Credits(int);
  241.  
  242. void ExitGame(int);
  243.  
  244. bool IsKeyPressedToGoBackToThePreviousMenu(int);
  245.  
  246. template <typename T>
  247.  
  248. void DifficultyMenu(T[], size_t, std::string[], size_t, std::string&, int);
  249.  
  250. void CoutCentered(const std::string&);
  251.  
  252. int main()
  253. {
  254.     FontSize(6);
  255.  
  256.     MaximizeWindow();
  257.  
  258.     ShowConsoleCursor(false);
  259.  
  260.     typedef void(*menuOptions)(int);
  261.  
  262.     menuOptions mainMenuOptions[] = { GameStart, Controls, Credits, ExitGame };
  263.  
  264.     size_t sizeOfTheArray = sizeof(mainMenuOptions) / sizeof(mainMenuOptions[0]);
  265.  
  266.     std::string mainMenu[] = { "Start Game", "Controls", "Credits", "Exit" };
  267.  
  268.     size_t sizeOfTheStringMenu = std::size(mainMenu);
  269.  
  270.     std::string text = "Main Menu";
  271.  
  272.     MainMenu(mainMenuOptions, sizeOfTheArray, mainMenu, sizeOfTheStringMenu, text, 0);
  273.  
  274.     return 0;
  275. }
  276.  
  277. template <typename T>
  278.  
  279. void MainMenu(T mainMenuOptions[], size_t sizeOfTheArray, std::string mainMenu[], size_t sizeOfTheStringMenu, std::string& text, int selectedOption)
  280. {
  281.     int key = 0;
  282.  
  283.     int previousSelectedOption = 0;
  284.  
  285.     while (true)
  286.     {
  287.         DisplayMenu(mainMenu, sizeOfTheStringMenu, text, selectedOption);
  288.  
  289.         previousSelectedOption = selectedOption;
  290.  
  291.         selectedOption = MenuMovement(mainMenuOptions, selectedOption, sizeOfTheArray, key);
  292.  
  293.         if (selectedOption < 0)
  294.         {
  295.             selectedOption = previousSelectedOption;
  296.         }
  297.  
  298.         std::this_thread::sleep_for(std::chrono::milliseconds(12));
  299.     }
  300. }
  301.  
  302. void DisplayMenu(std::string mainMenu[], size_t sizeOfTheStringMenu, std::string& text, const size_t& selectedOption)
  303. {
  304.     ClearScreen();
  305.  
  306.     std::cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  307.  
  308.     CoutCentered(text);
  309.  
  310.     std::cout << "\n" << "\n" << "\n";
  311.  
  312.     for (size_t i = 0; i < sizeOfTheStringMenu; i++)
  313.     {
  314.         selectedOption == i ? CoutCentered("--> " + mainMenu[i]) : CoutCentered("" + mainMenu[i]);
  315.  
  316.         if (i < sizeOfTheStringMenu - 1)
  317.         {
  318.             std::cout << "\n";
  319.         }
  320.     }
  321. }
  322.  
  323. /*
  324. This function is "int" and not "size_t", because the "size_t" data type doesn't return negative numbers,
  325. 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),
  326. in other words, only positive, including 0
  327. */
  328.  
  329. template <typename T>
  330.  
  331. int MenuMovement(T menu[], int selectedOption, size_t sizeOfTheArray, int key)
  332. {
  333.     key = KeyboardInput();
  334.  
  335.     if (key == upArrow)
  336.     {
  337.         selectedOption--;
  338.  
  339.         if (selectedOption < 0)
  340.         {
  341.             selectedOption = sizeOfTheArray - 1;
  342.         }
  343.     }
  344.  
  345.     else if (key == downArrow)
  346.     {
  347.         selectedOption++;
  348.  
  349.         if (selectedOption >= sizeOfTheArray)
  350.         {
  351.             selectedOption = 0;
  352.         }
  353.     }
  354.  
  355.     else if (key == enterKey)
  356.     {
  357.         menu[selectedOption](selectedOption);
  358.     }
  359.  
  360.     else if (key == escapeKey)
  361.     {
  362.         selectedOption = - 6;
  363.     }
  364.  
  365.     return selectedOption;
  366. }
  367.  
  368. void GameStart(int selectedOption)
  369. {
  370.     ClearScreen();
  371.  
  372.     std::cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  373.  
  374.     typedef void(*difficultyOptions)(int);
  375.  
  376.     difficultyOptions difficultyMenuOptions[] = { GameStart, Credits, ExitGame };
  377.  
  378.     size_t sizeOfTheArray = sizeof(difficultyMenuOptions) / sizeof(difficultyMenuOptions[0]);
  379.  
  380.     std::string difficultyMenu[] = { "Start", "Cdits", "Eit" };
  381.  
  382.     size_t sizeOfTheStringMenu = std::size(difficultyMenu);
  383.  
  384.     std::string text = "Difficulty Menu";
  385.  
  386.     DifficultyMenu(difficultyMenuOptions, sizeOfTheArray, difficultyMenu, sizeOfTheStringMenu, text, selectedOption);
  387. }
  388.  
  389. void Controls(int selectedOption)
  390. {
  391.     ClearScreen();
  392.  
  393.     std::cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  394.  
  395.     CoutCentered("The controls are showed!");
  396.  
  397.     while (!IsKeyPressedToGoBackToThePreviousMenu(KeyboardInput()));
  398. }
  399.  
  400. void Credits(int selectedOption)
  401. {
  402.     ClearScreen();
  403.  
  404.     std::cout << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n" << "\n";
  405.  
  406.     CoutCentered("The credits are showed!");
  407.  
  408.     while (!IsKeyPressedToGoBackToThePreviousMenu(KeyboardInput()));
  409. }
  410.  
  411. void ExitGame(int selectedOption)
  412. {
  413.     std::exit(0);
  414. }
  415.  
  416. bool IsKeyPressedToGoBackToThePreviousMenu(int key)
  417. {
  418.     if (key == escapeKey)
  419.     {
  420.         return true;
  421.     }
  422.  
  423.     return false;
  424. }
  425.  
  426. template <typename T>
  427.  
  428. void DifficultyMenu(T difficultyMenuOptions[], size_t sizeOfTheArray, std::string difficultyMenu[], size_t sizeOfTheStringMenu, std::string& text, int selectedOption)
  429. {
  430.     int key = 0;
  431.  
  432.     while (selectedOption != -6)
  433.     {
  434.         DisplayMenu(difficultyMenu, sizeOfTheStringMenu, text, selectedOption);
  435.  
  436.         selectedOption = MenuMovement(difficultyMenuOptions, selectedOption, sizeOfTheArray, key);
  437.  
  438.         std::this_thread::sleep_for(std::chrono::milliseconds(12));
  439.     }
  440. }
  441.  
  442. void CoutCentered(const std::string& text)
  443. {
  444.     size_t textWidth = text.length();
  445.  
  446.     short consoleWidth = GetConsoleSizes();
  447.  
  448.     size_t leftMargin = (consoleWidth - textWidth) / 2;
  449.  
  450.     std::cout.width(leftMargin + textWidth);
  451.  
  452.     std::cout << text;
  453. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement