Console.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  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 const Text& getName() const;
  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(const RCArray<Text>& args,
  63. bool appendToLast,
  64. RCArray<Text>& possibilities) const
  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) const = 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. /**
  307. * the current progress.
  308. *
  309. * \return the progress
  310. */
  311. DLLEXPORT int getProgress() const;
  312. protected:
  313. /**
  314. * prints the progress bar to the console.
  315. *
  316. * \return number of lines printed
  317. */
  318. DLLEXPORT virtual int print() const override;
  319. };
  320. class ConsoleListView;
  321. /**
  322. * a command input line where the user can type in commands. the user can
  323. * type the tab key for autocompletion.
  324. * ConsoleListView is used for displaying the autocompletion possibilities.
  325. */
  326. class InputLine : public StickyConsoleContent,
  327. private Thread
  328. {
  329. private:
  330. int cursorPos;
  331. RCArray<ConsoleCommand> commands;
  332. Critical cs;
  333. protected:
  334. Framework::Text input;
  335. ConsoleListView* suggestions;
  336. public:
  337. DLLEXPORT InputLine();
  338. DLLEXPORT ~InputLine();
  339. /**
  340. * ads a command to the list of possible commands used for
  341. * autocompletion and execution.
  342. *
  343. * \param command the command to add
  344. */
  345. DLLEXPORT void addPossibleCommand(ConsoleCommand* command);
  346. /**
  347. * returns true because the user can edit the content of this line.
  348. *
  349. * \return true
  350. */
  351. DLLEXPORT virtual bool isInput() override;
  352. protected:
  353. /**
  354. * called before all sticky console content is reprinted when isInput
  355. * is true. restoreCursorPos() must be called after this
  356. */
  357. DLLEXPORT virtual void setCursorToBeginning();
  358. /**
  359. * prints the input line to the console. restoreCursorPos must be called
  360. * later
  361. *
  362. * \return number of lines printed
  363. */
  364. DLLEXPORT virtual int print() const override;
  365. /**
  366. * reprints all input from the user so that the user can edit the
  367. * content again. can only be called after setCursorToBeginning was
  368. * called
  369. */
  370. DLLEXPORT virtual void restoreCursorPos() override;
  371. /**
  372. * writes the next autocomplete step to input or displays a list of
  373. * possibilities in suggestions.
  374. *
  375. */
  376. DLLEXPORT void applyAutocompletion();
  377. /**
  378. * executes a given command.
  379. *
  380. * \param command the command
  381. * \return true if the command was executed successfully
  382. */
  383. DLLEXPORT bool executeCommand(Text command);
  384. /**
  385. * splits a given command into its name and arguments.
  386. *
  387. * \param command the command to split
  388. * \param split the array with the name and arguments
  389. * \param lastFinished true if the last argument is finished (folowed by
  390. * a witespace or ending character)
  391. * \return true if the command was split successfully
  392. */
  393. DLLEXPORT bool parseCommand(
  394. Text command, RCArray<Text>& split, bool& lastFinished);
  395. private:
  396. DLLEXPORT void thread() override;
  397. friend ConsoleHandler;
  398. };
  399. /**
  400. * prints a list of words to the console. the list will be printed ordered
  401. * by ascii value. it can be organized in multiple columns.
  402. */
  403. class ConsoleListView : public StickyConsoleContent
  404. {
  405. private:
  406. int maxColumns;
  407. RCArray<Text> items;
  408. int maxVisibleLines;
  409. int lineOffset;
  410. public:
  411. DLLEXPORT ConsoleListView();
  412. /**
  413. * the number of columns used to display the complete list of words.
  414. *
  415. * \return the number of columns
  416. */
  417. DLLEXPORT int getUsedColumns() const;
  418. /**
  419. * the number of lines needed to display the complete list of words.
  420. *
  421. * \return the number of lines
  422. */
  423. DLLEXPORT int getNeededLines() const;
  424. /**
  425. * specifies the maximum amount of lines visible.
  426. *
  427. * \param maxVisibleLines the amount of lines
  428. */
  429. DLLEXPORT void setMaxVisibleLines(int maxVisibleLines);
  430. /**
  431. * specifies the offset of the first line that should be printed.
  432. *
  433. * \param lineOffset the index of the first line that is printed
  434. */
  435. DLLEXPORT void setLineOffset(int lineOffset);
  436. /**
  437. * specifies the maximum amount of columns used to display the list of
  438. * words.
  439. *
  440. * \param maxColumns the amount of columns
  441. */
  442. DLLEXPORT void setMaxColumns(int maxColumns);
  443. /**
  444. * adds a word to the list of words.
  445. *
  446. * \param item the word to add
  447. */
  448. DLLEXPORT void addItem(Text item);
  449. /**
  450. * removes all words from the list.
  451. */
  452. DLLEXPORT void clear();
  453. /**
  454. * the items in the list view.
  455. *
  456. * \return items
  457. */
  458. DLLEXPORT const RCArray<Text>& getItems() const;
  459. protected:
  460. /**
  461. * prints the list of words to the console.
  462. *
  463. * \return number of lines printed
  464. */
  465. DLLEXPORT virtual int print() const override;
  466. };
  467. enum class ConsoleContentPosition
  468. {
  469. /**
  470. * before all other sticky console content.
  471. */
  472. Top,
  473. /**
  474. * after all pther sticky console content.
  475. */
  476. Bottom,
  477. };
  478. class ConsoleHandler : public ReferenceCounter
  479. {
  480. private:
  481. StickyConsoleContent** lines;
  482. int* lineCounts;
  483. int contentCount;
  484. Critical cs;
  485. #ifdef WIN32
  486. HANDLE hConsole;
  487. #endif
  488. public:
  489. DLLEXPORT ConsoleHandler();
  490. DLLEXPORT ~ConsoleHandler();
  491. /**
  492. * adds a sticky console content to the console at a specified position.
  493. *
  494. * \param content the new content
  495. * \param pos the position of the new content
  496. */
  497. DLLEXPORT void addContent(
  498. StickyConsoleContent* content, ConsoleContentPosition pos);
  499. /**
  500. * removes a sticky console content from the list of displayed sticky
  501. * console content.
  502. *
  503. * \param zContent the content to remove without increasing the
  504. * reference counter
  505. */
  506. DLLEXPORT void removeContent(StickyConsoleContent* zContent);
  507. /**
  508. * the current with of the console window in characters.
  509. *
  510. * \return the with in characters
  511. */
  512. DLLEXPORT int getWidth() const;
  513. /**
  514. * the current height of the console window in characters.
  515. *
  516. * \return the height in characters
  517. */
  518. DLLEXPORT int getHeight() const;
  519. /**
  520. * removes all sticky console content from the list of displayed sticky
  521. * console content.
  522. */
  523. DLLEXPORT void clear();
  524. /**
  525. * reprints all sticky console content that is currently displayed.
  526. */
  527. DLLEXPORT void print();
  528. /**
  529. * prints something to the console at the position of the first sticky
  530. * console content and reprints all sticky console content below the
  531. * newly printed content.
  532. *
  533. * \param str the string to print
  534. */
  535. DLLEXPORT void print(Text str);
  536. public:
  537. friend InputLine;
  538. };
  539. } // namespace Framework