1/*
2 * Copyright 2007-2020 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _TEXTVIEW_H
6#define _TEXTVIEW_H
7
8
9#include <stdint.h>
10
11#include <Locker.h>
12#include <View.h>
13
14
15class BBitmap;
16class BClipboard;
17class BFile;
18class BList;
19class BMessageRunner;
20
21struct text_run {
22	int32		offset;
23	BFont		font;
24	rgb_color	color;
25};
26
27struct text_run_array {
28	int32		count;
29	text_run	runs[1];
30};
31
32enum undo_state {
33	B_UNDO_UNAVAILABLE,
34	B_UNDO_TYPING,
35	B_UNDO_CUT,
36	B_UNDO_PASTE,
37	B_UNDO_CLEAR,
38	B_UNDO_DROP
39};
40
41namespace BPrivate {
42	class TextGapBuffer;
43}
44
45
46class BTextView : public BView {
47public:
48								BTextView(BRect frame, const char* name,
49									BRect textRect, uint32 resizeMask,
50									uint32 flags
51										= B_WILL_DRAW | B_PULSE_NEEDED);
52								BTextView(BRect	frame, const char* name,
53									BRect textRect, const BFont* initialFont,
54									const rgb_color* initialColor,
55									uint32 resizeMask, uint32 flags);
56
57								BTextView(const char* name,
58									uint32 flags
59										= B_WILL_DRAW | B_PULSE_NEEDED);
60								BTextView(const char* name,
61									const BFont* initialFont,
62									const rgb_color* initialColor,
63									uint32 flags);
64
65								BTextView(BMessage* archive);
66
67	virtual						~BTextView();
68
69	static	BArchivable*		Instantiate(BMessage* archive);
70	virtual	status_t			Archive(BMessage* archive,
71									bool deep = true) const;
72
73	virtual	void				AttachedToWindow();
74	virtual	void				DetachedFromWindow();
75	virtual	void				Draw(BRect updateRect);
76	virtual	void				MouseDown(BPoint where);
77	virtual	void				MouseUp(BPoint where);
78	virtual	void				MouseMoved(BPoint where, uint32 code,
79									const BMessage* dragMessage);
80	virtual	void				WindowActivated(bool active);
81	virtual	void				KeyDown(const char* bytes, int32 numBytes);
82	virtual	void				Pulse();
83	virtual	void				FrameResized(float newWidth, float newHeight);
84	virtual	void				MakeFocus(bool focus = true);
85	virtual	void				MessageReceived(BMessage* message);
86
87	virtual	BHandler*			ResolveSpecifier(BMessage* message,
88									int32 index, BMessage* specifier,
89									int32 form, const char* property);
90	virtual	status_t			GetSupportedSuites(BMessage* data);
91	virtual	status_t			Perform(perform_code code, void* data);
92
93			void				SetText(const char* text,
94									const text_run_array* runs = NULL);
95			void				SetText(const char* text, int32 length,
96									const text_run_array* runs = NULL);
97			void				SetText(BFile* file, int32 offset,
98									int32 length,
99									const text_run_array* runs = NULL);
100
101			void				Insert(const char* text,
102									const text_run_array* runs = NULL);
103			void				Insert(const char* text, int32 length,
104									const text_run_array* runs = NULL);
105			void				Insert(int32 offset, const char* text,
106									int32 length,
107									const text_run_array* runs = NULL);
108
109			void				Delete();
110			void				Delete(int32 startOffset, int32 endOffset);
111
112			const char*			Text() const;
113			int32				TextLength() const;
114			void				GetText(int32 offset, int32 length,
115									char* buffer) const;
116			uint8				ByteAt(int32 offset) const;
117
118			int32				CountLines() const;
119			int32				CurrentLine() const;
120			void				GoToLine(int32 lineNumber);
121
122	virtual	void				Cut(BClipboard* clipboard);
123	virtual	void				Copy(BClipboard* clipboard);
124	virtual	void				Paste(BClipboard* clipboard);
125			void				Clear();
126
127	virtual	bool				AcceptsPaste(BClipboard* clipboard);
128	virtual	bool				AcceptsDrop(const BMessage* message);
129
130	virtual	void				Select(int32 startOffset, int32 endOffset);
131			void				SelectAll();
132			void				GetSelection(int32* _start, int32* _end) const;
133
134			void				SetFontAndColor(const BFont* font,
135									uint32 mode = B_FONT_ALL,
136									const rgb_color* color = NULL);
137			void				SetFontAndColor(int32 startOffset,
138									int32 endOffset, const BFont* font,
139									uint32 mode = B_FONT_ALL,
140									const rgb_color* color = NULL);
141
142			void				GetFontAndColor(int32 offset, BFont* _font,
143									rgb_color* _color = NULL) const;
144			void				GetFontAndColor(BFont* _font, uint32* _mode,
145									rgb_color* _color = NULL,
146									bool* _sameColor = NULL) const;
147
148			void				SetRunArray(int32 startOffset, int32 endOffset,
149									const text_run_array* runs);
150			text_run_array*		RunArray(int32 startOffset, int32 endOffset,
151									int32* _size = NULL) const;
152
153			int32				LineAt(int32 offset) const;
154			int32				LineAt(BPoint point) const;
155			BPoint				PointAt(int32 offset,
156									float* _height = NULL) const;
157			int32				OffsetAt(BPoint point) const;
158			int32				OffsetAt(int32 line) const;
159
160	virtual	void				FindWord(int32 offset, int32* _fromOffset,
161									int32* _toOffset);
162
163	virtual	bool				CanEndLine(int32 offset);
164
165			float				LineWidth(int32 lineNumber = 0) const;
166			float				LineHeight(int32 lineNumber = 0) const;
167			float				TextHeight(int32 startLine,
168									int32 endLine) const;
169
170			void				GetTextRegion(int32 startOffset,
171									int32 endOffset, BRegion* outRegion) const;
172
173	virtual	void				ScrollToOffset(int32 offset);
174			void				ScrollToSelection();
175
176			void				Highlight(int32 startOffset, int32 endOffset);
177
178			void				SetTextRect(BRect rect);
179			BRect				TextRect() const;
180			void				SetInsets(float left, float top, float right,
181									float bottom);
182			void				GetInsets(float* _left, float* _top,
183									float* _right, float* _bottom) const;
184
185			void				SetStylable(bool stylable);
186			bool				IsStylable() const;
187			void				SetTabWidth(float width);
188			float				TabWidth() const;
189			void				MakeSelectable(bool selectable = true);
190			bool				IsSelectable() const;
191			void				MakeEditable(bool editable = true);
192			bool				IsEditable() const;
193			void				SetWordWrap(bool wrap);
194			bool				DoesWordWrap() const;
195			void				SetMaxBytes(int32 max);
196			int32				MaxBytes() const;
197			void				DisallowChar(uint32 character);
198			void				AllowChar(uint32 character);
199			void				SetAlignment(alignment align);
200			alignment			Alignment() const;
201			void				SetAutoindent(bool state);
202			bool				DoesAutoindent() const;
203			void				SetColorSpace(color_space colors);
204			color_space			ColorSpace() const;
205			void				MakeResizable(bool resize,
206									BView* resizeView = NULL);
207			bool				IsResizable() const;
208			void				SetDoesUndo(bool undo);
209			bool				DoesUndo() const;
210			void				HideTyping(bool enabled);
211			bool				IsTypingHidden() const;
212
213	virtual	void				ResizeToPreferred();
214	virtual	void				GetPreferredSize(float* _width, float* _height);
215
216	virtual	void				AllAttached();
217	virtual	void				AllDetached();
218
219	static	text_run_array*		AllocRunArray(int32 entryCount,
220									int32* outSize = NULL);
221	static	text_run_array*		CopyRunArray(const text_run_array* orig,
222									int32 countDelta = 0);
223	static	void				FreeRunArray(text_run_array* array);
224	static	void*				FlattenRunArray(const text_run_array* runArray,
225									int32* _size = NULL);
226	static	text_run_array*		UnflattenRunArray(const void* data,
227									int32* _size = NULL);
228
229protected:
230	virtual	void				InsertText(const char* text, int32 length,
231									int32 offset, const text_run_array* runs);
232	virtual	void				DeleteText(int32 fromOffset, int32 toOffset);
233
234public:
235	virtual	void				Undo(BClipboard* clipboard);
236			undo_state			UndoState(bool* isRedo) const;
237
238protected:
239	virtual	void				GetDragParameters(BMessage* drag,
240									BBitmap** _bitmap, BPoint* point,
241									BHandler** _handler);
242
243	virtual	void				LayoutInvalidated(bool descendants);
244	virtual	void				DoLayout();
245
246public:
247	virtual	BSize				MinSize();
248	virtual	BSize				MaxSize();
249	virtual	BSize				PreferredSize();
250
251	virtual	bool				HasHeightForWidth();
252	virtual	void				GetHeightForWidth(float width, float* min,
253									float* max, float* preferred);
254
255private:
256	// FBC padding and forbidden methods
257	virtual	void				_ReservedTextView3();
258	virtual	void				_ReservedTextView4();
259	virtual	void				_ReservedTextView5();
260	virtual	void				_ReservedTextView6();
261	virtual	void				_ReservedTextView7();
262	virtual	void				_ReservedTextView8();
263	virtual	void				_ReservedTextView9();
264	virtual	void				_ReservedTextView10();
265	virtual	void				_ReservedTextView11();
266	virtual	void				_ReservedTextView12();
267
268private:
269			class InlineInput;
270			struct LayoutData;
271			class LineBuffer;
272			class StyleBuffer;
273			class TextTrackState;
274			class UndoBuffer;
275
276			// UndoBuffer derivatives
277			class CutUndoBuffer;
278			class PasteUndoBuffer;
279			class ClearUndoBuffer;
280			class DropUndoBuffer;
281			class TypingUndoBuffer;
282
283			friend class TextTrackState;
284
285			void				_InitObject(BRect textRect,
286									const BFont* initialFont,
287									const rgb_color* initialColor);
288
289			void				_ValidateLayoutData();
290			void				_ResetTextRect();
291
292			void				_HandleBackspace(int32 modifiers = -1);
293			void				_HandleArrowKey(uint32 arrowKey,
294									int32 modifiers = -1);
295			void				_HandleDelete(int32 modifiers = -1);
296			void				_HandlePageKey(uint32 pageKey,
297									int32 modifiers = -1);
298			void				_HandleAlphaKey(const char* bytes,
299									int32 numBytes);
300
301			void				_Refresh(int32 fromOffset, int32 toOffset,
302									int32 scrollTo = INT32_MIN);
303			void				_RecalculateLineBreaks(int32* startLine,
304									int32* endLine);
305			void				_ValidateTextRect();
306			int32				_FindLineBreak(int32 fromOffset,
307									float* _ascent, float* _descent,
308									float* inOutWidth);
309
310			float				_StyledWidth(int32 fromOffset, int32 length,
311									float* _ascent = NULL,
312									float* _descent = NULL) const;
313			float				_TabExpandedStyledWidth(int32 offset,
314									int32 length, float* _ascent = NULL,
315									float* _descent = NULL) const;
316
317			float				_ActualTabWidth(float location) const;
318
319			void				_DoInsertText(const char* text, int32 length,
320									int32 offset, const text_run_array* runs);
321
322			void				_DoDeleteText(int32 fromOffset,
323									int32 toOffset);
324
325			void				_DrawLine(BView* view, const int32 &startLine,
326									const int32& startOffset,
327									const bool& erase, BRect& eraseRect,
328									BRegion& inputRegion);
329
330			void				_DrawLines(int32 startLine, int32 endLine,
331									int32 startOffset = -1,
332									bool erase = false);
333			void				_RequestDrawLines(int32 startLine,
334									int32 endLine);
335
336			void				_DrawCaret(int32 offset, bool visible);
337			void				_ShowCaret();
338			void				_HideCaret();
339			void				_InvertCaret();
340			void				_DragCaret(int32 offset);
341
342			void				_StopMouseTracking();
343			bool				_PerformMouseUp(BPoint where);
344			bool				_PerformMouseMoved(BPoint where, uint32 code);
345
346			void				_TrackMouse(BPoint where,
347									const BMessage* message,
348									bool force = false);
349
350			void				_TrackDrag(BPoint where);
351			void				_InitiateDrag();
352			bool				_MessageDropped(BMessage* message,
353									BPoint where, BPoint offset);
354
355			void				_PerformAutoScrolling();
356			void				_UpdateScrollbars();
357			void				_ScrollBy(float horizontalStep,
358									float verticalStep);
359			void				_ScrollTo(float x, float y);
360
361			void				_AutoResize(bool doRedraw = true);
362
363			void				_NewOffscreen(float padding = 0.0);
364			void				_DeleteOffscreen();
365
366			void				_Activate();
367			void				_Deactivate();
368
369			void				_NormalizeFont(BFont* font);
370
371			void				_SetRunArray(int32 startOffset, int32 endOffset,
372									const text_run_array* runs);
373
374			void				_ApplyStyleRange(int32 fromOffset,
375									int32 toOffset,
376									uint32 mode = B_FONT_ALL,
377									const BFont* font = NULL,
378									const rgb_color* color = NULL,
379									bool syncNullStyle = true);
380
381			uint32				_CharClassification(int32 offset) const;
382			int32				_NextInitialByte(int32 offset) const;
383			int32				_PreviousInitialByte(int32 offset) const;
384
385			int32				_PreviousLineStart(int32 offset);
386			int32				_NextLineEnd(int32 offset);
387
388			int32				_PreviousWordBoundary(int32 offset);
389			int32				_NextWordBoundary(int32 offset);
390
391			int32				_PreviousWordStart(int32 offset);
392			int32				_NextWordEnd(int32 offset);
393
394			bool				_GetProperty(BMessage* message,
395									BMessage* specifier,
396									const char* property, BMessage* reply);
397			bool				_SetProperty(BMessage* message,
398									BMessage* specifier,
399									const char* property, BMessage* reply);
400			bool				_CountProperties(BMessage* message,
401									BMessage* specifier, const char* property,
402									BMessage* reply);
403
404			void				_HandleInputMethodChanged(BMessage* message);
405			void				_HandleInputMethodLocationRequest();
406			void				_CancelInputMethod();
407
408			int32				_LineAt(int32 offset) const;
409			int32				_LineAt(const BPoint& point) const;
410			bool				_IsOnEmptyLastLine(int32 offset) const;
411
412			float				_NullStyleHeight() const;
413
414			void				_ShowContextMenu(BPoint where);
415
416			void				_FilterDisallowedChars(char* text,
417									ssize_t& length, text_run_array* runArray);
418
419			void				_UpdateInsets(const BRect& rect);
420
421			float				_ViewWidth();
422			float				_ViewHeight();
423			BRect				_ViewRect();
424
425			float				_TextWidth();
426			float				_TextHeight();
427			BRect				_TextRect();
428
429private:
430			BPrivate::TextGapBuffer*	fText;
431			LineBuffer*			fLines;
432			StyleBuffer*		fStyles;
433			BRect				fTextRect;
434			int32				fSelStart;
435			int32				fSelEnd;
436			bool				fCaretVisible;
437			bigtime_t			fCaretTime;
438			int32				fCaretOffset;
439			int32				fClickCount;
440			bigtime_t			fClickTime;
441			int32				fDragOffset;
442			uint8				fCursor;
443			bool				fActive;
444			bool				fStylable;
445			float				fTabWidth;
446			bool				fSelectable;
447			bool				fEditable;
448			bool				fWrap;
449			int32				fMaxBytes;
450			BList*				fDisallowedChars;
451			alignment			fAlignment;
452			bool				fAutoindent;
453			BBitmap* 			fOffscreen;
454			color_space			fColorSpace;
455			bool				fResizable;
456			BView*				fContainerView;
457			UndoBuffer*			fUndo;
458			InlineInput*		fInline;
459			BMessageRunner*		fDragRunner;
460			BMessageRunner*		fClickRunner;
461			BPoint				fWhere;
462			TextTrackState*		fTrackingMouse;
463
464			float				fMinTextRectWidth;
465			LayoutData*			fLayoutData;
466			int32				fLastClickOffset;
467
468			bool				fInstalledNavigateCommandWordwiseShortcuts : 1;
469			bool				fInstalledNavigateOptionWordwiseShortcuts : 1;
470			bool				fInstalledNavigateOptionLinewiseShortcuts : 1;
471			bool				fInstalledNavigateHomeEndDocwiseShortcuts : 1;
472
473			bool				fInstalledSelectCommandWordwiseShortcuts : 1;
474			bool				fInstalledSelectOptionWordwiseShortcuts : 1;
475			bool				fInstalledSelectOptionLinewiseShortcuts : 1;
476			bool				fInstalledSelectHomeEndDocwiseShortcuts : 1;
477
478			bool				fInstalledRemoveCommandWordwiseShortcuts : 1;
479			bool				fInstalledRemoveOptionWordwiseShortcuts : 1;
480
481			uint32				_reserved[6];
482};
483
484#endif	// _TEXTVIEW_H
485