Console.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. #pragma once
  2. #include "Array.h"
  3. #include "Critical.h"
  4. #include "ReferenceCounter.h"
  5. #include "Text.h"
  6. #include "Thread.h"
  7. namespace Framework
  8. {
  9. class ConsoleHandler;
  10. enum class Color
  11. {
  12. Black,
  13. RED,
  14. GREEN,
  15. YELLOW,
  16. Blue,
  17. Magenta,
  18. CYAN,
  19. WHITE,
  20. LIGHT_Black,
  21. LIGHT_RED,
  22. LIGHT_GREEN,
  23. LIGHT_YELLOW,
  24. LIGHT_Blue,
  25. LIGHT_Magenta,
  26. LIGHT_CYAN,
  27. LIGHT_WHITE,
  28. };
  29. /**
  30. * simple console command interface used for autocompletion and execution of
  31. * commands
  32. */
  33. class ConsoleCommand : public ReferenceCounter
  34. {
  35. private:
  36. Text name;
  37. public:
  38. /**
  39. * creates a new command
  40. *
  41. * \param name the name of the command. if the user types this name into
  42. * the console at the beginning, the command will be executed
  43. */
  44. DLLEXPORT ConsoleCommand(Text name);
  45. DLLEXPORT virtual ~ConsoleCommand();
  46. /**
  47. * the name of the command
  48. *
  49. * \return the name
  50. */
  51. DLLEXPORT Text& getName();
  52. /**
  53. * calculates autocomplete posibilities when the user presses the tab
  54. * key and wants to use this command
  55. *
  56. * \param args the current arguments that would be passed to the command
  57. * if it was executed
  58. * \param appendToLast true if the last argument is not finished
  59. * \param possibilities the array to which the
  60. * possibilities should be added
  61. */
  62. virtual void addAutocompletePossibilities(RCArray<Text>& args,
  63. bool appendToLast,
  64. RCArray<Text>& possibilities)
  65. = 0;
  66. /**
  67. * executes the command
  68. *
  69. * \param args the arguments that the user has passed to the command
  70. * \return true if the command was executed successfully
  71. */
  72. virtual bool execute(RCArray<Text>& args) = 0;
  73. };
  74. /**
  75. * repesents console content that is sticky, meaning it stays in the console
  76. * even if other messages are printed or commands are executed
  77. */
  78. class StickyConsoleContent : public virtual ReferenceCounter
  79. {
  80. private:
  81. int length;
  82. char* content;
  83. Color* color;
  84. Color* backgroundColor;
  85. ConsoleHandler* zConsoleHandler;
  86. public:
  87. DLLEXPORT StickyConsoleContent();
  88. DLLEXPORT ~StickyConsoleContent();
  89. /**
  90. * the current length of the command.
  91. *
  92. * \return the length in characters including possible newlines
  93. */
  94. DLLEXPORT int getLength() const;
  95. /**
  96. * sets the current content of the command. all previous colors will be
  97. * removed. does not free any memory of the given arguments.
  98. *
  99. * \param length the new length in characters
  100. * \param content the new content
  101. */
  102. DLLEXPORT void setContent(int length, const char* content);
  103. /**
  104. * sets the current content of the command. all previous colors will be
  105. * removed. does not free any memory of the given arguments.
  106. *
  107. * \param length the new length in characters
  108. * \param content the new content
  109. * \param color the font color of the content
  110. */
  111. DLLEXPORT void setContent(int length, const char* content, Color color);
  112. /**
  113. * sets the current content of the command. all previous colors will be
  114. * removed. does not free any memory of the given arguments.
  115. *
  116. * \param length the new length in characters
  117. * \param content the new content
  118. * \param color the font color of the content
  119. * \param backgroundColor the background color of the content
  120. */
  121. DLLEXPORT void setContent(int length,
  122. const char* content,
  123. Color color,
  124. Color backgroundColor);
  125. /**
  126. * sets the current content of the command. all previous colors will be
  127. * removed. does not free any memory of the given arguments.
  128. *
  129. * \param length the new length in characters
  130. * \param content the new content
  131. * \param color array of font colors for each character
  132. */
  133. DLLEXPORT void setContent(
  134. int length, const char* content, Color* color);
  135. /**
  136. * sets the current content of the command. all previous colors will be
  137. * removed. does not free any memory of the given arguments.
  138. *
  139. * \param length the new length in characters
  140. * \param content the new content
  141. * \param color array of font colors for each character
  142. * \param backgroundColor array of background colors for each character
  143. */
  144. DLLEXPORT void setContent(int length,
  145. const char* content,
  146. Color* color,
  147. Color* backgroundColor);
  148. /**
  149. * replaces a part of the current content. the colors of the current
  150. * start position will be used for the new content. does not free any
  151. * memory of the given arguments.
  152. *
  153. * \param start the start position of the replacement
  154. * \param length the length of the content that should be replaced
  155. * \param newLength the length of the new content that should be
  156. * inserted instead of the old content
  157. * \param newContent the new content
  158. */
  159. DLLEXPORT void repaceContent(
  160. int start, int length, int newLength, const char* newContent);
  161. /**
  162. * replaces a part of the current content. the backgound color of the
  163. * current start position will be used for the new content. does not
  164. * free any memory of the given arguments.
  165. *
  166. * \param start the start position of the replacement
  167. * \param length the length of the content that should be replaced
  168. * \param newLength the length of the new content that should be
  169. * inserted instead of the old content
  170. * \param newContent the new content
  171. * \param color the font color of the new content
  172. */
  173. DLLEXPORT void repaceContent(int start,
  174. int length,
  175. int newLength,
  176. const char* newContent,
  177. Color color);
  178. /**
  179. * replaces a part of the current content. does not
  180. * free any memory of the given arguments.
  181. *
  182. * \param start the start position of the replacement
  183. * \param length the length of the content that should be replaced
  184. * \param newLength the length of the new content that should be
  185. * inserted instead of the old content
  186. * \param newContent the new content
  187. * \param color the font color of the new content
  188. * \param backgroundColor the background color of the new content
  189. */
  190. DLLEXPORT void repaceContent(int start,
  191. int length,
  192. int newLength,
  193. const char* newContent,
  194. Color color,
  195. Color backgroundColor);
  196. /**
  197. * replaces a part of the current content. the backgound color of the
  198. * current start position will be used for the new content. does not
  199. * free any memory of the given arguments.
  200. *
  201. * \param start the start position of the replacement
  202. * \param length the length of the content that should be replaced
  203. * \param newLength the length of the new content that should be
  204. * inserted instead of the old content
  205. * \param newContent the new content
  206. * \param color array the font colorc of the new content for each
  207. * character
  208. */
  209. DLLEXPORT void repaceContent(int start,
  210. int length,
  211. int newLength,
  212. const char* newContent,
  213. Color* color);
  214. /**
  215. * replaces a part of the current content. does not
  216. * free any memory of the given arguments.
  217. *
  218. * \param start the start position of the replacement
  219. * \param length the length of the content that should be replaced
  220. * \param newLength the length of the new content that should be
  221. * inserted instead of the old content
  222. * \param newContent the new content
  223. * \param color array the font colorc of the new content for each
  224. * character
  225. * \param backgroundColor the background color of the new content for
  226. * each character
  227. */
  228. DLLEXPORT void repaceContent(int start,
  229. int length,
  230. int newLength,
  231. const char* newContent,
  232. Color* color,
  233. Color* backgroundColor);
  234. /**
  235. * triggers reprinting of all sticky console content.
  236. */
  237. DLLEXPORT void triggerUpdate();
  238. /**
  239. * true if the content is a input line where the user can type in
  240. *
  241. * \param true if the user can edit this content
  242. */
  243. DLLEXPORT virtual bool isInput();
  244. public:
  245. /**
  246. * prints the content to the console
  247. *
  248. * \return number of lines printed
  249. */
  250. DLLEXPORT virtual int print() const;
  251. /**
  252. * sets the console handler instance where this content will be printed
  253. * to. This will automatically be done if the content is added to a
  254. * consolehandler.
  255. *
  256. * \param zConsoleHandler the handler instance without increasing the
  257. * reference counter
  258. */
  259. DLLEXPORT void setConsoleHandlerZ(ConsoleHandler* zConsoleHandler);
  260. protected:
  261. /**
  262. * called before all sticky console content is reprinted when isInput
  263. * is true. restoreCursorPos() must be called after this
  264. */
  265. DLLEXPORT virtual void setCursorToBeginning();
  266. /**
  267. * reprints all input from the user so that the user can edit the
  268. * content again. can only be called after setCursorToBeginning was
  269. * called
  270. */
  271. DLLEXPORT virtual void restoreCursorPos();
  272. ConsoleHandler* zConsoleHandlerRef() const;
  273. public:
  274. friend ConsoleHandler;
  275. };
  276. /**
  277. * displays a progress bar in the console.
  278. */
  279. class ConsoleProgressBar : public StickyConsoleContent
  280. {
  281. private:
  282. int progress;
  283. int maxProgress;
  284. int maxWidth;
  285. public:
  286. DLLEXPORT ConsoleProgressBar();
  287. /**
  288. * sets the max used with of the progress bar in charachters including
  289. * the percentage number.
  290. *
  291. * \param maxWidth the width in characters
  292. */
  293. DLLEXPORT void setMaxWidth(int maxWidth);
  294. /**
  295. * sets the current progress.
  296. *
  297. * \param progress the progress
  298. */
  299. DLLEXPORT void setProgress(int progress);
  300. /**
  301. * sets the max progress steps needed to reach 100% progress.
  302. *
  303. * \param maxProgress max progress
  304. */
  305. DLLEXPORT void setMaxProgress(int maxProgress);
  306. protected:
  307. /**
  308. * prints the progress bar to the console.
  309. *
  310. * \return number of lines printed
  311. */
  312. DLLEXPORT virtual int print() const override;
  313. };
  314. class ConsoleListView;
  315. /**
  316. * a command input line where the user can type in commands. the user can
  317. * type the tab key for autocompletion.
  318. * ConsoleListView is used for displaying the autocompletion possibilities.
  319. */
  320. class InputLine : public StickyConsoleContent,
  321. private Thread
  322. {
  323. private:
  324. int cursorPos;
  325. RCArray<ConsoleCommand> commands;
  326. Critical cs;
  327. protected:
  328. Framework::Text input;
  329. ConsoleListView* suggestions;
  330. public:
  331. DLLEXPORT InputLine();
  332. DLLEXPORT ~InputLine();
  333. /**
  334. * ads a command to the list of possible commands used for
  335. * autocompletion and execution.
  336. *
  337. * \param command the command to add
  338. */
  339. DLLEXPORT void addPossibleCommand(ConsoleCommand* command);
  340. /**
  341. * returns true because the user can edit the content of this line.
  342. *
  343. * \return true
  344. */
  345. DLLEXPORT virtual bool isInput() override;
  346. protected:
  347. /**
  348. * called before all sticky console content is reprinted when isInput
  349. * is true. restoreCursorPos() must be called after this
  350. */
  351. DLLEXPORT virtual void setCursorToBeginning();
  352. /**
  353. * prints the input line to the console. restoreCursorPos must be called
  354. * later
  355. *
  356. * \return number of lines printed
  357. */
  358. DLLEXPORT virtual int print() const override;
  359. /**
  360. * reprints all input from the user so that the user can edit the
  361. * content again. can only be called after setCursorToBeginning was
  362. * called
  363. */
  364. DLLEXPORT virtual void restoreCursorPos() override;
  365. /**
  366. * writes the next autocomplete step to input or displays a list of
  367. * possibilities in suggestions.
  368. *
  369. */
  370. DLLEXPORT void applyAutocompletion();
  371. /**
  372. * executes a given command.
  373. *
  374. * \param command the command
  375. * \return true if the command was executed successfully
  376. */
  377. DLLEXPORT bool executeCommand(Text command);
  378. /**
  379. * splits a given command into its name and arguments.
  380. *
  381. * \param command the command to split
  382. * \param split the array with the name and arguments
  383. * \param lastFinished true if the last argument is finished (folowed by
  384. * a witespace or ending character)
  385. * \return true if the command was split successfully
  386. */
  387. DLLEXPORT bool parseCommand(
  388. Text command, RCArray<Text>& split, bool& lastFinished);
  389. private:
  390. DLLEXPORT void thread() override;
  391. friend ConsoleHandler;
  392. };
  393. /**
  394. * prints a list of words to the console. the list will be printed ordered
  395. * by ascii value. it can be organized in multiple columns.
  396. */
  397. class ConsoleListView : public StickyConsoleContent
  398. {
  399. private:
  400. int maxColumns;
  401. RCArray<Text> items;
  402. int maxVisibleLines;
  403. int lineOffset;
  404. public:
  405. DLLEXPORT ConsoleListView();
  406. /**
  407. * the number of columns used to display the complete list of words.
  408. *
  409. * \return the number of columns
  410. */
  411. DLLEXPORT int getUsedColumns() const;
  412. /**
  413. * the number of lines needed to display the complete list of words.
  414. *
  415. * \return the number of lines
  416. */
  417. DLLEXPORT int getNeededLines() const;
  418. /**
  419. * specifies the maximum amount of lines visible.
  420. *
  421. * \param maxVisibleLines the amount of lines
  422. */
  423. DLLEXPORT void setMaxVisibleLines(int maxVisibleLines);
  424. /**
  425. * specifies the offset of the first line that should be printed.
  426. *
  427. * \param lineOffset the index of the first line that is printed
  428. */
  429. DLLEXPORT void setLineOffset(int lineOffset);
  430. /**
  431. * specifies the maximum amount of columns used to display the list of
  432. * words.
  433. *
  434. * \param maxColumns the amount of columns
  435. */
  436. DLLEXPORT void setMaxColumns(int maxColumns);
  437. /**
  438. * adds a word to the list of words.
  439. *
  440. * \param item the word to add
  441. */
  442. DLLEXPORT void addItem(Text item);
  443. /**
  444. * removes all words from the list.
  445. */
  446. DLLEXPORT void clear();
  447. /**
  448. * the items in the list view.
  449. *
  450. * \return items
  451. */
  452. DLLEXPORT const RCArray<Text>& getItems() const;
  453. protected:
  454. /**
  455. * prints the list of words to the console.
  456. *
  457. * \return number of lines printed
  458. */
  459. DLLEXPORT virtual int print() const override;
  460. };
  461. enum class ConsoleContentPosition
  462. {
  463. /**
  464. * before all other sticky console content.
  465. */
  466. Top,
  467. /**
  468. * after all pther sticky console content.
  469. */
  470. Bottom,
  471. };
  472. class ConsoleHandler : public ReferenceCounter
  473. {
  474. private:
  475. StickyConsoleContent** lines;
  476. int* lineCounts;
  477. int contentCount;
  478. Critical cs;
  479. #ifdef WIN32
  480. HANDLE hConsole;
  481. #endif
  482. public:
  483. DLLEXPORT ConsoleHandler();
  484. DLLEXPORT ~ConsoleHandler();
  485. /**
  486. * adds a sticky console content to the console at a specified position.
  487. *
  488. * \param content the new content
  489. * \param pos the position of the new content
  490. */
  491. DLLEXPORT void addContent(
  492. StickyConsoleContent* content, ConsoleContentPosition pos);
  493. /**
  494. * removes a sticky console content from the list of displayed sticky
  495. * console content.
  496. *
  497. * \param zContent the content to remove without increasing the
  498. * reference counter
  499. */
  500. DLLEXPORT void removeContent(StickyConsoleContent* zContent);
  501. /**
  502. * the current with of the console window in characters.
  503. *
  504. * \return the with in characters
  505. */
  506. DLLEXPORT int getWidth() const;
  507. /**
  508. * the current height of the console window in characters.
  509. *
  510. * \return the height in characters
  511. */
  512. DLLEXPORT int getHeight() const;
  513. /**
  514. * removes all sticky console content from the list of displayed sticky
  515. * console content.
  516. */
  517. DLLEXPORT void clear();
  518. /**
  519. * reprints all sticky console content that is currently displayed.
  520. */
  521. DLLEXPORT void print();
  522. /**
  523. * prints something to the console at the position of the first sticky
  524. * console content and reprints all sticky console content below the
  525. * newly printed content.
  526. *
  527. * \param str the string to print
  528. */
  529. DLLEXPORT void print(Text str);
  530. public:
  531. friend InputLine;
  532. };
  533. } // namespace Framework