xref: /haiku/src/apps/icon-o-matic/generic/gui/InputTextView.cpp (revision 16d5c24e533eb14b7b8a99ee9f3ec9ba66335b1e)
1 /*
2  * Copyright 2006, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus <superstippi@gmx.de>
7  */
8 
9 #include "InputTextView.h"
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 
14 #include <String.h>
15 
16 // constructor
17 InputTextView::InputTextView(BRect frame, const char* name,
18 							 BRect textRect,
19 							 uint32 resizingMode,
20 							 uint32 flags)
21 	: BTextView(frame, name, textRect, resizingMode, flags),
22 	  fWasFocus(false)
23 {
24 	SetWordWrap(false);
25 }
26 
27 // destructor
28 InputTextView::~InputTextView()
29 {
30 }
31 
32 // MouseDown
33 void
34 InputTextView::MouseDown(BPoint where)
35 {
36 	// enforce the behaviour of a typical BTextControl
37 	// only let the BTextView handle mouse up/down when
38 	// it already had focus
39 	fWasFocus = IsFocus();
40 	if (fWasFocus) {
41 		BTextView::MouseDown(where);
42 	} else {
43 		// forward click
44 		if (BView* view = Parent()) {
45 			view->MouseDown(ConvertToParent(where));
46 		}
47 	}
48 }
49 
50 // MouseUp
51 void
52 InputTextView::MouseUp(BPoint where)
53 {
54 	// enforce the behaviour of a typical BTextControl
55 	// only let the BTextView handle mouse up/down when
56 	// it already had focus
57 	if (fWasFocus)
58 		BTextView::MouseUp(where);
59 }
60 
61 // KeyDown
62 void
63 InputTextView::KeyDown(const char* bytes, int32 numBytes)
64 {
65 	bool handled = true;
66 	if (numBytes > 0) {
67 		switch (bytes[0]) {
68 			case B_ESCAPE:
69 				// revert any typing changes
70 				RevertChanges();
71 				break;
72 			case B_TAB:
73 				// skip BTextView implementation
74 				BView::KeyDown(bytes, numBytes);
75 				// fall through
76 			case B_RETURN:
77 				ApplyChanges();
78 				break;
79 			default:
80 				handled = false;
81 				break;
82 		}
83 	}
84 	if (!handled)
85 		BTextView::KeyDown(bytes, numBytes);
86 }
87 
88 // MakeFocus
89 void
90 InputTextView::MakeFocus(bool focus)
91 {
92 	if (focus != IsFocus()) {
93 		if (BView* view = Parent())
94 			view->Invalidate();
95 		BTextView::MakeFocus(focus);
96 		if (focus)
97 			SelectAll();
98 	}
99 }
100 
101 // Invoke
102 status_t
103 InputTextView::Invoke(BMessage* message)
104 {
105 	if (!message)
106 		message = Message();
107 
108 	if (message) {
109 		BMessage copy(*message);
110 		copy.AddInt64("when", system_time());
111 		copy.AddPointer("source", (BView*)this);
112 		return BInvoker::Invoke(&copy);
113 	}
114 	return B_BAD_VALUE;
115 }
116 
117 // #pragma mark -
118 
119 // Select
120 void
121 InputTextView::Select(int32 start, int32 finish)
122 {
123 	BTextView::Select(start, finish);
124 
125 	_CheckTextRect();
126 }
127 
128 // InsertText
129 void
130 InputTextView::InsertText(const char* inText, int32 inLength, int32 inOffset,
131 						  const text_run_array* inRuns)
132 {
133 	BTextView::InsertText(inText, inLength, inOffset, inRuns);
134 
135 	_CheckTextRect();
136 }
137 
138 // DeleteText
139 void
140 InputTextView::DeleteText(int32 fromOffset, int32 toOffset)
141 {
142 	BTextView::DeleteText(fromOffset, toOffset);
143 
144 	_CheckTextRect();
145 }
146 
147 // #pragma mark -
148 
149 // _CheckTextRect
150 void
151 InputTextView::_CheckTextRect()
152 {
153 	// update text rect and make sure
154 	// the cursor/selection is in view
155 	BRect textRect(TextRect());
156 	float width = ceilf(StringWidth(Text()) + 2.0);
157 	if (textRect.Width() != width) {
158 		textRect.right = textRect.left + width;
159 		SetTextRect(textRect);
160 		ScrollToSelection();
161 	}
162 }
163