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