xref: /haiku/src/apps/deskcalc/InputTextView.cpp (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
1 /*
2  * Copyright 2006 Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus, superstippi@gmx.de
7  */
8 
9 
10 #include "InputTextView.h"
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 
15 #include <String.h>
16 
17 
18 InputTextView::InputTextView(BRect frame, const char* name, BRect textRect,
19 	uint32 resizingMode, uint32 flags)
20 	:
21 	BTextView(frame, name, textRect, resizingMode, flags),
22 	fWasFocus(false)
23 {
24 	SetWordWrap(false);
25 }
26 
27 
28 InputTextView::~InputTextView()
29 {
30 }
31 
32 
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 
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 
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 
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 
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 
118 // #pragma mark -
119 
120 
121 void
122 InputTextView::Select(int32 start, int32 finish)
123 {
124 	BTextView::Select(start, finish);
125 
126 	_CheckTextRect();
127 }
128 
129 
130 void
131 InputTextView::InsertText(const char* inText, int32 inLength, int32 inOffset,
132 	const text_run_array* inRuns)
133 {
134 	BTextView::InsertText(inText, inLength, inOffset, inRuns);
135 
136 	_CheckTextRect();
137 }
138 
139 
140 void
141 InputTextView::DeleteText(int32 fromOffset, int32 toOffset)
142 {
143 	BTextView::DeleteText(fromOffset, toOffset);
144 
145 	_CheckTextRect();
146 }
147 
148 
149 // #pragma mark -
150 
151 
152 void
153 InputTextView::_CheckTextRect()
154 {
155 	// update text rect and make sure
156 	// the cursor/selection is in view
157 	BRect textRect(TextRect());
158 	float width = ceilf(StringWidth(Text()) + 2.0);
159 	if (textRect.Width() < width) {
160 		textRect.right = textRect.left + width;
161 		SetTextRect(textRect);
162 		ScrollToSelection();
163 	}
164 }
165