lltextbase.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:19k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file lltextbase.h
  3.  * @author Martin Reddy
  4.  * @brief The base class of text box/editor, providing Url handling support
  5.  *
  6.  * $LicenseInfo:firstyear=2009&license=viewergpl$
  7.  * 
  8.  * Copyright (c) 2009-2010, Linden Research, Inc.
  9.  * 
  10.  * Second Life Viewer Source Code
  11.  * The source code in this file ("Source Code") is provided by Linden Lab
  12.  * to you under the terms of the GNU General Public License, version 2.0
  13.  * ("GPL"), unless you have obtained a separate licensing agreement
  14.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  15.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17.  * 
  18.  * There are special exceptions to the terms and conditions of the GPL as
  19.  * it is applied to this Source Code. View the full text of the exception
  20.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  21.  * online at
  22.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23.  * 
  24.  * By copying, modifying or distributing this software, you acknowledge
  25.  * that you have read and understood your obligations described above,
  26.  * and agree to abide by those obligations.
  27.  * 
  28.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30.  * COMPLETENESS OR PERFORMANCE.
  31.  * $/LicenseInfo$
  32.  */
  33. #ifndef LL_LLTEXTBASE_H
  34. #define LL_LLTEXTBASE_H
  35. #include "v4color.h"
  36. #include "lleditmenuhandler.h"
  37. #include "llstyle.h"
  38. #include "llkeywords.h"
  39. #include "llpanel.h"
  40. #include <string>
  41. #include <vector>
  42. #include <set>
  43. #include <boost/signals2.hpp>
  44. class LLContextMenu;
  45. class LLTextSegment;
  46. class LLNormalTextSegment;
  47. typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
  48. ///
  49. /// The LLTextBase class provides a base class for all text fields, such
  50. /// as LLTextEditor and LLTextBox. It implements shared functionality
  51. /// such as Url highlighting and opening.
  52. ///
  53. class LLTextBase 
  54. : public LLUICtrl,
  55. protected LLEditMenuHandler
  56. {
  57. public:
  58. friend class LLTextSegment;
  59. friend class LLNormalTextSegment;
  60. struct LineSpacingParams : public LLInitParam::Choice<LineSpacingParams>
  61. {
  62. Alternative<F32> multiple;
  63. Alternative<S32> pixels;
  64. LineSpacingParams();
  65. };
  66. struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
  67. {
  68. Optional<LLUIColor> cursor_color,
  69. text_color,
  70. text_readonly_color,
  71. bg_readonly_color,
  72. bg_writeable_color,
  73. bg_focus_color;
  74. Optional<bool> bg_visible,
  75. border_visible,
  76. track_end,
  77. read_only,
  78. allow_scroll,
  79. wrap,
  80. use_ellipses,
  81. allow_html,
  82. parse_highlights,
  83. clip_partial;
  84. Optional<S32> v_pad,
  85. h_pad;
  86. Optional<LineSpacingParams>
  87. line_spacing;
  88. Optional<S32> max_text_length;
  89. Optional<LLFontGL::ShadowType> font_shadow;
  90. Params();
  91. };
  92. // LLMouseHandler interface
  93. /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
  94. /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
  95. /*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
  96. /*virtual*/ BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask);
  97. /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
  98. /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
  99. /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
  100. /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
  101. /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
  102. /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
  103. // LLView interface
  104. /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
  105. /*virtual*/ void draw();
  106. // LLUICtrl interface
  107. /*virtual*/ BOOL acceptsTextInput() const { return !mReadOnly; }
  108. /*virtual*/ void setColor( const LLColor4& c );
  109. virtual     void  setReadOnlyColor(const LLColor4 &c);
  110. virtual     void handleVisibilityChange( BOOL new_visibility );
  111. /*virtual*/ void setValue(const LLSD& value );
  112. /*virtual*/ LLTextViewModel* getViewModel() const;
  113. // LLEditMenuHandler interface
  114. /*virtual*/ void deselect();
  115. // used by LLTextSegment layout code
  116. bool getWordWrap() { return mWordWrap; }
  117. bool getUseEllipses() { return mUseEllipses; }
  118. bool truncate(); // returns true of truncation occurred
  119. // TODO: move into LLTextSegment?
  120. void createUrlContextMenu(S32 x, S32 y, const std::string &url); // create a popup context menu for the given Url
  121. // Text accessors
  122. // TODO: add optional style parameter
  123. virtual void setText(const LLStringExplicit &utf8str , const LLStyle::Params& input_params = LLStyle::Params()); // uses default style
  124. virtual std::string getText() const;
  125. void setMaxTextLength(S32 length) { mMaxTextByteLength = length; }
  126. // wide-char versions
  127. void setWText(const LLWString& text);
  128. const LLWString&        getWText() const;
  129. void appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params());
  130. // force reflow of text
  131. void needsReflow(S32 index = 0);
  132. S32 getLength() const { return getWText().length(); }
  133. S32 getLineCount() const { return mLineInfoList.size(); }
  134. void addDocumentChild(LLView* view);
  135. void removeDocumentChild(LLView* view);
  136. const LLView* getDocumentView() const { return mDocumentView; }
  137. LLRect getVisibleTextRect() { return mVisibleTextRect; }
  138. LLRect getTextBoundingRect();
  139. LLRect getVisibleDocumentRect() const;
  140. S32 getVPad() { return mVPad; }
  141. S32 getHPad() { return mHPad; }
  142. S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, bool hit_past_end_of_line = true) const;
  143. LLRect getLocalRectFromDocIndex(S32 pos) const;
  144. LLRect getDocRectFromDocIndex(S32 pos) const;
  145. void setReadOnly(bool read_only) { mReadOnly = read_only; }
  146. bool getReadOnly() { return mReadOnly; }
  147. // cursor manipulation
  148. bool setCursor(S32 row, S32 column);
  149. bool setCursorPos(S32 cursor_pos, bool keep_cursor_offset = false);
  150. void startOfLine();
  151. void endOfLine();
  152. void startOfDoc();
  153. void endOfDoc();
  154. void changePage( S32 delta );
  155. void changeLine( S32 delta );
  156. bool scrolledToStart();
  157. bool scrolledToEnd();
  158. const LLFontGL* getDefaultFont() const { return mDefaultFont; }
  159. public:
  160. // Fired when a URL link is clicked
  161. commit_signal_t mURLClickSignal;
  162. protected:
  163. // helper structs
  164. struct compare_bottom;
  165. struct compare_top;
  166. struct line_end_compare;
  167. typedef std::vector<LLTextSegmentPtr> segment_vec_t;
  168. // Abstract inner base class representing an undoable editor command.
  169. // Concrete sub-classes can be defined for operations such as insert, remove, etc.
  170. // Used as arguments to the execute() method below.
  171. class TextCmd
  172. {
  173. public:
  174. TextCmd( S32 pos, BOOL group_with_next, LLTextSegmentPtr segment = LLTextSegmentPtr() ) 
  175. : mPos(pos), 
  176. mGroupWithNext(group_with_next)
  177. {
  178. if (segment.notNull())
  179. {
  180. mSegments.push_back(segment);
  181. }
  182. }
  183. virtual ~TextCmd() {}
  184. virtual BOOL execute(LLTextBase* editor, S32* delta) = 0;
  185. virtual S32 undo(LLTextBase* editor) = 0;
  186. virtual S32 redo(LLTextBase* editor) = 0;
  187. virtual BOOL canExtend(S32 pos) const { return FALSE; }
  188. virtual void blockExtensions() {}
  189. virtual BOOL extendAndExecute( LLTextBase* editor, S32 pos, llwchar c, S32* delta ) { llassert(0); return 0; }
  190. virtual BOOL hasExtCharValue( llwchar value ) const { return FALSE; }
  191. // Defined here so they can access protected LLTextEditor editing methods
  192. S32 insert(LLTextBase* editor, S32 pos, const LLWString &wstr) { return editor->insertStringNoUndo( pos, wstr, &mSegments ); }
  193. S32  remove(LLTextBase* editor, S32 pos, S32 length) { return editor->removeStringNoUndo( pos, length ); }
  194. S32 overwrite(LLTextBase* editor, S32 pos, llwchar wc) { return editor->overwriteCharNoUndo(pos, wc); }
  195. S32 getPosition() const { return mPos; }
  196. BOOL groupWithNext() const { return mGroupWithNext; }
  197. protected:
  198. const S32 mPos;
  199. BOOL mGroupWithNext;
  200. segment_vec_t mSegments;
  201. };
  202. struct compare_segment_end
  203. {
  204. bool operator()(const LLTextSegmentPtr& a, const LLTextSegmentPtr& b) const;
  205. };
  206. typedef std::multiset<LLTextSegmentPtr, compare_segment_end> segment_set_t;
  207. // protected member variables
  208. // List of offsets and segment index of the start of each line.  Always has at least one node (0).
  209. struct line_info
  210. {
  211. line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num);
  212. S32 mDocIndexStart;
  213. S32 mDocIndexEnd;
  214. LLRect mRect;
  215. S32 mLineNum; // actual line count (ignoring soft newlines due to word wrap)
  216. };
  217. typedef std::vector<line_info> line_list_t;
  218. // member functions
  219. LLTextBase(const Params &p);
  220. virtual ~LLTextBase();
  221. void initFromParams(const Params& p);
  222. virtual void onValueChange(S32 start, S32 end);
  223. // draw methods
  224. void drawSelectionBackground(); // draws the black box behind the selected text
  225. void drawCursor();
  226. void drawText();
  227. // modify contents
  228. S32 insertStringNoUndo(S32 pos, const LLWString &wstr, segment_vec_t* segments = NULL); // returns num of chars actually inserted
  229. S32  removeStringNoUndo(S32 pos, S32 length);
  230. S32 overwriteCharNoUndo(S32 pos, llwchar wc);
  231. void appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& stylep);
  232. // manage segments 
  233. void                 getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const;
  234. void                 getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp );
  235. LLTextSegmentPtr     getSegmentAtLocalPos( S32 x, S32 y, bool hit_past_end_of_line = true);
  236. segment_set_t::iterator getSegIterContaining(S32 index);
  237. segment_set_t::const_iterator getSegIterContaining(S32 index) const;
  238. void                 clearSegments();
  239. void createDefaultSegment();
  240. virtual void updateSegments();
  241. void insertSegment(LLTextSegmentPtr segment_to_insert);
  242. LLStyle::Params getDefaultStyleParams();
  243. //  manage lines
  244. S32 getLineStart( S32 line ) const;
  245. S32 getLineEnd( S32 line ) const;
  246. S32 getLineNumFromDocIndex( S32 doc_index, bool include_wordwrap = true) const;
  247. S32 getLineOffsetFromDocIndex( S32 doc_index, bool include_wordwrap = true) const;
  248. S32 getFirstVisibleLine() const;
  249. std::pair<S32, S32> getVisibleLines(bool fully_visible = false);
  250. S32 getLeftOffset(S32 width);
  251. void reflow();
  252. // cursor
  253. void updateCursorXPos();
  254. void setCursorAtLocalPos( S32 local_x, S32 local_y, bool round, bool keep_cursor_offset=false );
  255. S32 getEditableIndex(S32 index, bool increasing_direction); // constraint cursor to editable segments of document
  256. void resetCursorBlink() { mCursorBlinkTimer.reset(); }
  257. void updateScrollFromCursor();
  258. // text selection
  259. bool hasSelection() const { return (mSelectionStart !=mSelectionEnd); }
  260. void  startSelection();
  261. void  endSelection();
  262. // misc
  263. void updateRects();
  264. void needsScroll() { mScrollNeeded = TRUE; }
  265. void replaceUrlLabel(const std::string &url, const std::string &label);
  266. protected:
  267. // text segmentation and flow
  268. segment_set_t        mSegments;
  269. line_list_t mLineInfoList;
  270. LLRect mVisibleTextRect; // The rect in which text is drawn.  Excludes borders.
  271. LLRect mTextBoundingRect;
  272. // colors
  273. LLUIColor mCursorColor;
  274. LLUIColor mFgColor;
  275. LLUIColor mReadOnlyFgColor;
  276. LLUIColor mWriteableBgColor;
  277. LLUIColor mReadOnlyBgColor;
  278. LLUIColor mFocusBgColor;
  279. // cursor
  280. S32 mCursorPos; // I-beam is just after the mCursorPos-th character.
  281. S32 mDesiredXPixel; // X pixel position where the user wants the cursor to be
  282. LLFrameTimer mCursorBlinkTimer;  // timer that controls cursor blinking
  283. // selection
  284. S32 mSelectionStart;
  285. S32 mSelectionEnd;
  286. BOOL mIsSelecting; // Are we in the middle of a drag-select? 
  287. // configuration
  288. S32 mHPad; // padding on left of text
  289. S32 mVPad; // padding above text
  290. LLFontGL::HAlign mHAlign;
  291. F32 mLineSpacingMult; // multiple of line height used as space for a single line of text (e.g. 1.5 to get 50% padding)
  292. S32 mLineSpacingPixels; // padding between lines
  293. const LLFontGL* mDefaultFont; // font that is used when none specified
  294. LLFontGL::ShadowType mFontShadow;
  295. bool mBorderVisible;
  296. bool                 mParseHTML; // make URLs interactive
  297. bool mParseHighlights; // highlight user-defined keywords
  298. bool                 mWordWrap;
  299. bool mUseEllipses;
  300. bool mTrackEnd; // if true, keeps scroll position at end of document during resize
  301. bool mReadOnly;
  302. bool mBGVisible; // render background?
  303. bool mClipPartial; // false if we show lines that are partially inside bounding rect
  304. S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
  305. // support widgets
  306. LLContextMenu* mPopupMenu;
  307. LLView* mDocumentView;
  308. class LLScrollContainer* mScroller;
  309. // transient state
  310. S32 mReflowIndex; // index at which to start reflow.  S32_MAX indicates no reflow needed.
  311. bool mScrollNeeded; // need to change scroll region because of change to cursor position
  312. S32 mScrollIndex; // index of first character to keep visible in scroll region
  313. };
  314. ///
  315. /// A text segment is used to specify a subsection of a text string
  316. /// that should be formatted differently, such as a hyperlink. It
  317. /// includes a start/end offset from the start of the string, a
  318. /// style to render with, an optional tooltip, etc.
  319. ///
  320. class LLTextSegment : public LLRefCount, public LLMouseHandler
  321. {
  322. public:
  323. LLTextSegment(S32 start, S32 end) : mStart(start), mEnd(end){};
  324. virtual ~LLTextSegment();
  325. virtual bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
  326. virtual S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
  327. virtual S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
  328. virtual void updateLayout(const class LLTextBase& editor);
  329. virtual F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
  330. virtual bool canEdit() const;
  331. virtual void unlinkFromDocument(class LLTextBase* editor);
  332. virtual void linkToDocument(class LLTextBase* editor);
  333. virtual const LLColor4& getColor() const;
  334. //virtual void  setColor(const LLColor4 &color);
  335. virtual LLStyleConstSP getStyle() const;
  336. virtual void  setStyle(LLStyleConstSP style);
  337. virtual void setToken( LLKeywordToken* token );
  338. virtual LLKeywordToken* getToken() const;
  339. virtual void setToolTip(const std::string& tooltip);
  340. virtual void dump() const;
  341. // LLMouseHandler interface
  342. /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
  343. /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
  344. /*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
  345. /*virtual*/ BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask);
  346. /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
  347. /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
  348. /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
  349. /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
  350. /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
  351. /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
  352. /*virtual*/ std::string getName() const;
  353. /*virtual*/ void onMouseCaptureLost();
  354. /*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const;
  355. /*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const;
  356. /*virtual*/ BOOL hasMouseCapture();
  357. S32 getStart() const  { return mStart; }
  358. void setStart(S32 start) { mStart = start; }
  359. S32 getEnd() const { return mEnd; }
  360. void setEnd( S32 end ) { mEnd = end; }
  361. protected:
  362. S32 mStart;
  363. S32 mEnd;
  364. };
  365. class LLNormalTextSegment : public LLTextSegment
  366. {
  367. public:
  368. LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor );
  369. LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
  370. ~LLNormalTextSegment();
  371. /*virtual*/ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
  372. /*virtual*/ S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
  373. /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
  374. /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
  375. /*virtual*/ bool canEdit() const { return true; }
  376. /*virtual*/ const LLColor4& getColor() const { return mStyle->getColor(); }
  377. /*virtual*/ LLStyleConstSP getStyle() const { return mStyle; }
  378. /*virtual*/ void  setStyle(LLStyleConstSP style) { mStyle = style; }
  379. /*virtual*/ void setToken( LLKeywordToken* token ) { mToken = token; }
  380. /*virtual*/ LLKeywordToken* getToken() const { return mToken; }
  381. /*virtual*/ BOOL getToolTip( std::string& msg ) const;
  382. /*virtual*/ void setToolTip(const std::string& tooltip);
  383. /*virtual*/ void dump() const;
  384. /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
  385. /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
  386. /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
  387. /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
  388. /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
  389. protected:
  390. F32 drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRect rect);
  391. protected:
  392. class LLTextBase& mEditor;
  393. LLStyleConstSP mStyle;
  394. S32 mFontHeight;
  395. LLKeywordToken*  mToken;
  396. std::string      mTooltip;
  397. boost::signals2::connection mImageLoadedConnection;
  398. };
  399. class LLIndexSegment : public LLTextSegment
  400. {
  401. public:
  402. LLIndexSegment(S32 pos) : LLTextSegment(pos, pos) {}
  403. };
  404. class LLInlineViewSegment : public LLTextSegment
  405. {
  406. public:
  407. struct Params : public LLInitParam::Block<Params>
  408. {
  409. Mandatory<LLView*> view;
  410. Optional<bool> force_newline;
  411. Optional<S32> left_pad,
  412. right_pad,
  413. bottom_pad,
  414. top_pad;
  415. };
  416. LLInlineViewSegment(const Params& p, S32 start, S32 end);
  417. ~LLInlineViewSegment();
  418. /*virtual*/ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
  419. /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
  420. /*virtual*/ void updateLayout(const class LLTextBase& editor);
  421. /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
  422. /*virtual*/ bool canEdit() const { return false; }
  423. /*virtual*/ void unlinkFromDocument(class LLTextBase* editor);
  424. /*virtual*/ void linkToDocument(class LLTextBase* editor);
  425. private:
  426. S32 mLeftPad;
  427. S32 mRightPad;
  428. S32 mTopPad;
  429. S32 mBottomPad;
  430. LLView* mView;
  431. bool mForceNewLine;
  432. };
  433. #endif