Subversion Repositories Kolibri OS

Rev

Rev 5323 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /******************************************************************
  2. *   21 days: a game for programmers
  3. *   Copyright (C) 2014 Maxim Grishin
  4. *
  5. *   This program is free software; you can redistribute it and/or
  6. *   modify it under the terms of the GNU General Public License
  7. *   as published by the Free Software Foundation; either version 2
  8. *   of the License, or (at your option) any later version.
  9. *
  10. *   This program is distributed in the hope that it will be useful,
  11. *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. *   GNU General Public License for more details.
  14. *
  15. *   You should have received a copy of the GNU General Public License
  16. *   along with this program; if not, write to the Free Software
  17. *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  18. *   MA  02110-1301, USA.
  19. *******************************************************************/
  20.  
  21. #include "sys.h"
  22.  
  23. #ifndef _KOS32
  24. #include <stdio.h> // printf()
  25. #include <stdarg.h>
  26. #define printf2 printf
  27. #endif
  28.  
  29. #include <cstring> // strlen
  30. #include <string>
  31. using std::string;
  32.  
  33. char getAnswer(char a1, char a2) {
  34.     while(1) {
  35.         if (kbhit()) {
  36.             char ch = getch();
  37.             #ifdef _KOS32
  38.             if (ch == 0)
  39.               ch = getch();
  40.             #endif
  41.             if (ch == a1 || ch == a2)
  42.                 return ch;
  43.             }
  44.         }
  45.     }
  46.  
  47. char getAnswer(char a1, char a2, char a3) {
  48.     while(1) {
  49.         if (kbhit()) {
  50.             char ch = getch();
  51.             #ifdef _KOS32
  52.             if (ch == 0)
  53.               ch = getch();
  54.             #endif
  55.             if (ch == a1 || ch == a2 || ch == a3)
  56.                 return ch;
  57.             }
  58.         }
  59.     }
  60.  
  61. char getAnswer(char a1, char a2, char a3, char a4) {
  62.     while(1) {
  63.         if (kbhit()) {
  64.             char ch = getch();
  65.             #ifdef _KOS32
  66.             if (ch == 0)
  67.               ch = getch();
  68.             #endif
  69.             if (ch == a1 || ch == a2 || ch == a3 || ch == a4)
  70.                 return ch;
  71.             }
  72.         }
  73.     }
  74.    
  75. void wait(char a = ENTER_KEY, char b = ENTER_KEY) {
  76.     getAnswer(a, b);
  77.     }
  78.    
  79. char getKey() {
  80. #ifdef _KOS32
  81.     while(1) {
  82.     if (kbhit()) {
  83.         char ch = getch();
  84.         if (ch == 0)
  85.             ch = getch();
  86.         return ch;
  87.         }
  88.     }
  89. #else
  90.     return getch();
  91. #endif
  92.     }
  93.  
  94. void blankline(int line, int width) {
  95.     printf2("º ");
  96.     consoleGoto(line, width);
  97.     printf2(\n");
  98.     }
  99.    
  100. void drawHBorder(int line, int left, int right, char l = 'É',
  101.                  char c = 'Í', char r = '»', char e = '\n') {
  102.     consoleGoto(line, left);
  103.     printf2("%c", l);
  104.     for (int i = 0; i< right - left; i++)
  105.         printf2("%c", c);
  106.     consoleGoto(line, right);
  107.     printf2("%c%c", r, e);
  108.     }
  109.  
  110. void drawStringLine(int line, int left, int right, const char* str,
  111.                     int pos = -1, char border = 'º', bool shadow = false) {
  112.     consoleGoto(line, left);
  113.     if (pos == -1)
  114.         printf2("%c %s", border, str);
  115.     else {
  116.         printf2("%c ", border);
  117.         consoleGoto(line, pos);
  118.         printf2("%s", str);
  119.         }
  120.     consoleGoto(line, right);
  121.     if (shadow)
  122.         printf2("%cÛ", border);
  123.     else
  124.         printf2("%c\n", border);
  125.     }
  126.    
  127. void drawModalWindow(const char* content, const char* title, const char* buttons) {
  128.     cls();  
  129.     int winWidth, winHeight;
  130.     getWinWH(winWidth, winHeight);
  131.     int lines = winHeight/3;
  132.     int msgWidth = strlen(content)+2;
  133.  
  134.     if (msgWidth >= winWidth-4)
  135.         msgWidth = winWidth-5;
  136.     int msgLeft = winWidth/2 - msgWidth/2;
  137.     int msgRight = winWidth/2 + msgWidth/2+1;
  138.     if (msgWidth%2!=0)
  139.         msgRight++;
  140.  
  141.     int titleWidth = 0;
  142.     if (title != 0)
  143.         titleWidth = strlen(title)+2;
  144.  
  145.     drawHBorder(lines, msgLeft, msgRight,'Õ','Í', '¸');
  146.    
  147.     // title
  148.     if (title != 0) {
  149.         consoleGoto(lines, msgLeft+msgWidth/2-titleWidth/2);
  150.         printf2(" %s ", title);
  151.         }
  152.  
  153.     lines++;
  154.     drawHBorder(lines, msgLeft, msgRight, '³',' ','³','Û');
  155.     lines++;
  156.    
  157.     //======Splitting content into pieces=========================
  158.     int maxTextWidth = msgRight-msgLeft; // 2 borders + 2 spaces
  159.     int start = 0;
  160.     int len = strlen(content);
  161.  
  162.     for (int i = 0; i < len; i++) {
  163.         if (content[i] == '\n') {
  164.             string tmp = content;
  165.             string t1 = tmp.substr(start, i-start+1);
  166.             drawStringLine(lines, msgLeft, msgRight, t1.c_str(), -1, '³', true);
  167.  
  168.             start = i+1;
  169.             lines++;
  170.             }
  171.         else if (i - start >= maxTextWidth-3) {
  172.             string tmp = content;
  173.             string t1 = tmp.substr(start, i-start);
  174.             t1+="\n";
  175.             drawStringLine(lines, msgLeft, msgRight, t1.c_str(), -1, '³', true);
  176.             start = i;
  177.             lines++;
  178.             }
  179.         }
  180.     if (start != len) {
  181.         string tmp = content;
  182.         string t1 = tmp.substr(start, len-start);
  183.         drawStringLine(lines, msgLeft, msgRight, t1.c_str(), -1, '³', true);
  184.         lines++;
  185.         }
  186.     //===============================
  187.     drawHBorder(lines, msgLeft, msgRight, '³',' ','³','Û');
  188.     lines++;
  189.  
  190.     consoleGoto(lines, msgLeft);
  191.     printf2("³");
  192.     if (!buttons) {
  193.         for (int q = 0; q< msgWidth/2-4;q++)
  194.             printf2(" ");
  195.         printf2("[Enter]");
  196.         for (int i = 0; i< msgWidth/2-2; i++)
  197.             printf2(" ");
  198.         }
  199.     else {
  200.         int buttonsLen = strlen(buttons);
  201.         for (int i = 0; i < msgWidth/2-buttonsLen/2; i++)
  202.             printf2(" ");
  203.         printf2("%s", buttons);
  204.         }
  205.     consoleGoto(lines, msgRight);
  206.     printf2("³Û");
  207.     lines++;
  208.  
  209.     drawHBorder(lines, msgLeft, msgRight,'À', 'Ä', 'Ù','Û');
  210.     lines++;
  211.    
  212.     consoleGoto(lines, msgLeft+1);
  213.     for (int i = 0; i< msgWidth+2; i++)
  214.         printf2("ß");
  215.     printf2(" ");
  216.     }
  217.    
  218. void drawWindow(string content, const char* title, string topline , string bottomline, bool usePagesForLongText = false) {
  219.     cls();
  220.     int winWidth, winHeight;
  221.     getWinWH(winWidth, winHeight);
  222.  
  223. #if defined(_WIN32) && !defined(_KOS32)
  224.     int deltaX = 0;
  225. #else
  226.     int deltaX = 1;
  227. #endif
  228.    
  229.     // Total lines
  230. #if defined(_WIN32) && !defined(_KOS32)
  231.     int lines = 0;
  232. #else
  233.     int lines = 1;
  234. #endif
  235.    
  236.     // Top
  237.     drawHBorder(lines, deltaX, winWidth);
  238.     lines++;
  239.  
  240.     if (topline != "") {
  241.         drawStringLine(lines, deltaX, winWidth, topline.c_str());
  242.         lines++;
  243.         }
  244.     // Title
  245.     if (title != 0) {
  246.         if (topline != "") {
  247.             blankline(lines, winWidth);
  248.             lines++;
  249.         }
  250.         drawStringLine(lines, deltaX, winWidth, title, (int)(winWidth/2.0-strlen(title)/2.0));
  251.         lines++;
  252.         blankline(lines, winWidth);
  253.         lines++;
  254.         }
  255.  
  256.     //==========Splitting content into pieces=====================
  257.     int maxTextWidth = winWidth-4; // 2 borders + 2 spaces
  258.     int start = 0;
  259.     unsigned int i = 0;
  260.     // Let's split content into pieces if it too long or doesn't fit the screen
  261.     while (i < content.length()) {
  262.         if (usePagesForLongText && lines > winHeight-3) {
  263.           consoleGoto(lines, 0);
  264.           blankline(lines, winWidth);
  265.           lines++;
  266.           drawStringLine(lines, deltaX, winWidth, " ¦¬¨â¥ [Enter] ¤«ï ¯à®¤®«¦¥­¨ï...");
  267.           // Bottom line
  268.           drawHBorder(winHeight, deltaX, winWidth,'È','Í','¼');
  269.           wait();
  270.           // Print next page
  271.           cls();
  272.           lines = 0;
  273.           // Top line
  274.           drawHBorder(lines, deltaX, winWidth);
  275.           #if defined(_WIN32) && !defined(_KOS32)
  276.           lines = 1;
  277.           #else
  278.           lines = 2;
  279.           #endif
  280.         }
  281.         // Use <c> tag to place text in the center
  282.         if (content[i] == '<') {
  283.             // Checking for the <c> tag. <c> tag should be prepended with '\n'
  284.             if (i+2 < content.length()) {
  285.                 if (content[i+1] == 'c' && content[i+2] == '>') {
  286.                     // Tag found. Looking for the end of a string
  287.                     int cLineEnd = content.length()-1;
  288.                     for (unsigned int j = i; j < content.length(); j++)
  289.                         if (content[j] == '\n') {
  290.                             cLineEnd = j;
  291.                             break;
  292.                             }
  293.                     int cLineWidth = cLineEnd - i-1;
  294.                     drawStringLine(lines, deltaX, winWidth,
  295.                                 content.substr(i+3, cLineWidth-2).c_str(), winWidth/2-cLineWidth/2);
  296.                     i = cLineEnd+1;
  297.                     start = i;
  298.                     lines++;
  299.                     continue;
  300.                     }
  301.                 }
  302.             }
  303.         else if (content[i] == '\n') {
  304.             consoleGoto(lines, 0);
  305.             string t1 = content.substr(start, i-start+1);
  306.             drawStringLine(lines, deltaX, winWidth, t1.c_str());
  307.             start = i+1;
  308.             lines++;
  309.             }
  310.         else if ((int)i - start >= maxTextWidth-1) {
  311.             consoleGoto(lines, 0);
  312.             string t1 = content.substr(start, i-start);
  313.             t1+="\n";
  314.             drawStringLine(lines, deltaX, winWidth, t1.c_str());
  315.             start = i;
  316.             lines++;
  317.             }
  318.           i++;
  319.         }
  320.     if (start <= (int)content.length()) {
  321.         consoleGoto(lines, 0);
  322.         string t1 = content.substr(start, content.length()-start);
  323.         drawStringLine(lines, deltaX, winWidth, t1.c_str());
  324.         lines++;
  325.         }
  326.     //===============================
  327.  
  328.     for (int i = lines; i< winHeight; i++) {
  329.         blankline(lines, winWidth);
  330.         lines++;
  331.         }
  332.  
  333.     if (!bottomline.empty()) {
  334.         ///Fix for long bottomline
  335.         if ((int)bottomline.length() >= winWidth) {
  336.             drawStringLine(winHeight-2, deltaX, winWidth, bottomline.substr(0, winWidth-4).c_str());
  337.             drawStringLine(winHeight-1, deltaX, winWidth, bottomline.substr(winWidth-4).c_str());
  338.             }
  339.         else {
  340.             drawStringLine(winHeight-1, deltaX, winWidth, bottomline.c_str());
  341.             }
  342.         }
  343.     // Bottom
  344.     drawHBorder(winHeight, deltaX, winWidth,'È','Í','¼');
  345.     }