gcsx_editbox.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /* GCSx
  2. ** EDITBOX.H
  3. **
  4. ** Multi-line textbox window
  5. */
  6. /*****************************************************************************
  7. ** Copyright (C) 2003-2006 Janson
  8. **
  9. ** This program is free software; you can redistribute it and/or modify
  10. ** it under the terms of the GNU General Public License as published by
  11. ** the Free Software Foundation; either version 2 of the License, or
  12. ** (at your option) any later version.
  13. **
  14. ** This program is distributed in the hope that it will be useful,
  15. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. ** GNU General Public License for more details.
  18. **
  19. ** You should have received a copy of the GNU General Public License
  20. ** along with this program; if not, write to the Free Software
  21. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
  22. *****************************************************************************/
  23. #ifndef __GCSx_EDITBOX_H_
  24. #define __GCSx_EDITBOX_H_
  25. // d) Data line- one line in storage
  26. // v) Virtual line- one line displayed
  27. // One data line results in one OR MORE virtual lines
  28. class EditBox : public Window {
  29. public:
  30. // Definition of a point within textbox- points to the character it is before
  31. struct TextPoint {
  32. int vRow;
  33. int column;
  34. int pixelX;
  35. };
  36. protected:
  37. // Maps virtual lines to data
  38. struct VLine {
  39. int dLine;
  40. std::list<std::string>::iterator dLineI;
  41. int colStart; // first row will have 0
  42. int length; // length of 5 means chars 0-4 plus a blank spot at the end
  43. const std::string getStr() const { return (*dLineI).substr(colStart, length); }
  44. };
  45. std::list<VLine> lineMap;
  46. void fillLineMap();
  47. // Returns number of vlines added
  48. // doesn't update vNumLines or dNumLines; does update vLongestLength
  49. int addLineWrapped(int dLine, std::list<std::string>::iterator& iter, std::list<VLine>::iterator& insertAt);
  50. int breakLineBefore(const std::string& line, int xPixel);
  51. // Assumes contents, starting at given line, have been deleted or added already
  52. // Call in sequence for a modification of x lines
  53. // Doesn't adjust insertion/selection, resize, or dirty
  54. // (insert adjusts vLongestLength)
  55. void eraseLineMap(int dLineFirst, int count, int* getVLineAt = NULL, int* getVLineCount = NULL);
  56. void insertLineMap(int dLineAt, int count, int* getVLineAt = NULL, int* getVLineCount = NULL);
  57. void dumpLineMap();
  58. // Adjusts cursor/selection and resizes
  59. void contentModifyHelper(int vLine, int vCount);
  60. // Call if you modify within a single line only- does everything except update insertion/selection
  61. // and doesn't call pre/post modify
  62. // Assumes you've called vLineToDLineAllPoints and that points are in dlines right now
  63. // (update linemap, resize, dirty)
  64. // All changes that don't go through pasteText() go through this function
  65. void modifyDLine(int dLine);
  66. // Helper function
  67. void doIndent(int dLine, int count, int function);
  68. int open;
  69. int haveFocus;
  70. class FrameWindow* myFrame;
  71. class WidgetScroll* myScroll;
  72. int font;
  73. int readonly;
  74. int wordwrap;
  75. int wrappedTo;
  76. int autoIndent;
  77. // Dirty range, in Vlines
  78. int vDirtyFirst;
  79. int vDirtyLast;
  80. // A copy of storage for convenience
  81. std::list<std::string>* contents;
  82. int dNumLines;
  83. int vNumLines;
  84. int vLongestLength; // In pixels
  85. int lineHeight;
  86. // Iterator control for quickly finding a spot in the middle
  87. std::list<VLine>::iterator lastSpot;
  88. int lastSpotLine;
  89. std::list<VLine>::iterator findVLine(int line);
  90. // Finds FIRST of a given data line
  91. std::list<VLine>::iterator findDLine(int dLine, int* getVLineNum = NULL);
  92. // Insertion point and selection
  93. // Selection begin OR end will ALWAYS match insertpoint UNLESS
  94. // there is no selection, in which case both are indeterminate
  95. TextPoint insertion;
  96. TextPoint selectBegin;
  97. TextPoint selectEnd;
  98. int isSelect;
  99. // Insertion point
  100. int insertYOffset;
  101. int insertHeight;
  102. int insertBlink;
  103. Uint32 insertBlinkMs;
  104. // Characters that make up "words"
  105. static const std::string wordChars;
  106. enum {
  107. GUI_EDITBOX_INSERTPOINTWIDTH = 2,
  108. // Margin is blank space inside textbox border
  109. GUI_EDITBOX_INNERMARGIN = 0,
  110. // Padding is added to edges of text within textbox, but only shows when
  111. // fully scrolled to that end of the text
  112. GUI_EDITBOX_LEFTPAD = 3,
  113. GUI_EDITBOX_RIGHTPAD = 3,
  114. // Preferred number of pixels to show in excess on each side when scrolling
  115. GUI_EDITBOX_SCROLLAHEAD = 10,
  116. // MS to wait between blinks
  117. DELAY_CURSOR_BLINK = 500,
  118. // These only apply when used as a widget!
  119. // This is the number of X characters to fit in a standard width
  120. GUI_EDITBOX_DEFAULTWIDTH = 30,
  121. // Default number of lines to show
  122. GUI_EDITBOX_DEFAULTLINES = 20,
  123. // Tab size (replaced with spaces)
  124. TAB_SIZE = 3,
  125. };
  126. // Sets dirty and resets cursor blink
  127. void setDirtyAndBlink();
  128. // Sets range of lines dirty
  129. void setDirtyRange(int first, int last);
  130. // Move one character left or right; pixelX will not be accurate
  131. void goLeft(TextPoint& point);
  132. void goRight(TextPoint& point);
  133. // Convert a textpoint from vline to dline position and back
  134. // A dline textpoint is useless until converted back, but can be
  135. // used to help retain relative position when doing modifications
  136. // Converting to VLine also updates xpixel.
  137. void vLineToDLine(TextPoint& point);
  138. void dLineToVLine(TextPoint& point);
  139. void vLineToDLineAllPoints();
  140. void dLineToVLineAllPoints();
  141. // Called whenever content changes, BEFORE and AFTER it changes
  142. // Will consist of any number of operations (in any order) ending in DONE
  143. // Reminder: line numbers are 0-based
  144. enum ContentChangeType {
  145. EDITBOX_REMOVE_LINES = 1,
  146. EDITBOX_INSERT_LINES, // It's assumed these are modified as well
  147. EDITBOX_MODIFY_LINE, // Only one at a time
  148. EDITBOX_MODIFY_DONE, // Called after each batch (even if just one) of modifications
  149. };
  150. virtual void contentModifiedPre(ContentChangeType type, int firstRow, int numRows);
  151. virtual void contentModifiedPost(ContentChangeType type, int firstRow, int numRows);
  152. // Update titlebar of frame
  153. virtual void updateTitlebar();
  154. virtual void prepOpen();
  155. virtual void paintText(const std::string& text, const std::string& entireLine, int posInLine, int x, int y, SDL_Surface* destSurface, int isSelected = 0) const;
  156. public:
  157. // Edited directly in storage
  158. EditBox(std::list<std::string>* storage, int myFont = FONT_STANDARD, int isReadOnly = 0);
  159. virtual ~EditBox();
  160. virtual int event(int hasFocus, const SDL_Event* event);
  161. void load();
  162. void apply();
  163. void display(SDL_Surface* destSurface, Rect& toDisplay, const Rect& clipArea, int xOffset, int yOffset);
  164. virtual CommandSupport supportsCommand(int code) const;
  165. WindowType windowType() const;
  166. // Creates a FrameWindow, adds self to desktop
  167. class FrameWindow* runWindowed();
  168. // Adds self to dialog using a WScroll
  169. void addTo(class Dialog* dialog, int showWidth = -1, int showLines = -1);
  170. // Returns the insertion position, given a pixel X/Y offset; X/Y offset
  171. // does not need to be within the actual display boundaries (IE you can drag
  172. // past the edges) .pixelX member is not accurate
  173. TextPoint insertWhere(int x, int y);
  174. // Same, but given a row instead of y pixel
  175. TextPoint insertWhereRow(int x, int row);
  176. // Handle special keystrokes
  177. void keyBackspace();
  178. void keyDelete();
  179. void indent(int dLine, int count);
  180. void unindent(int dLine, int count);
  181. // Query or set the insertion point, which also clears selection and
  182. // scrolls if needed to view; if drag is true, this drags the current
  183. // insertion point to the given position, modifying the selection as well
  184. const TextPoint& insertionState() const;
  185. // .pixelX member does not need to be accurate
  186. // .pixelX member is modified to be accurate in original and return
  187. // no other modifications are done to newPos
  188. const TextPoint& insertionState(TextPoint& newPos, int drag = 0);
  189. // (sel = ins if no selection at this time)
  190. void getCursorData(TextPoint& ins, TextPoint& selBegin, TextPoint& selEnd) const;
  191. // Intended to be called during undo process, but should be safe regardless
  192. // May change .pixelX members- but not gauranteed
  193. void setCursorData(TextPoint& ins, TextPoint& selBegin, TextPoint& selEnd);
  194. // Selects entire text, scrolls to end
  195. void selectAll();
  196. // Inserts text at the insertion point, overwriting any selection
  197. // No text = clear selection
  198. // Newlines are interpreted
  199. // Resets selection and adjusts insertion and scroll points
  200. // MOST changes go through this function; see modifyDLine
  201. void pasteText(const std::string& text);
  202. // Alerts editbox that its contents have changed in some way
  203. // Automatically handles dirty, scroll, moving insertion point, etc as needed
  204. // (line numbers 0-based)
  205. // Lines are DATA lines
  206. void contentModify(int dLine, int countLines);
  207. void contentInsert(int dLine, int countLines);
  208. void contentDelete(int dLine, int countLines);
  209. // Copies current selection to buffer
  210. // Copies "" if no selection
  211. // Newlines are inserted between lines
  212. void copyText(std::string& buffer);
  213. // Are we open?
  214. int isOpen() const { return open; }
  215. void resize(int newWidth, int newHeight, int newViewWidth = -1, int newViewHeight = -1, int fromParent = 0);
  216. };
  217. #endif