2 * Copyright 2001-2015, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Frans van Nispen (xlr8@tref.nl)
7 * Marc Flerackers (mflerackers@androme.be)
11 #include "TextInput.h"
17 #include <ControlLook.h>
18 #include <InterfaceDefs.h>
19 #include <LayoutUtils.h>
22 #include <TextControl.h>
30 _BTextInput_::_BTextInput_(BRect frame
, BRect textRect
, uint32 resizeMask
,
33 BTextView(frame
, "_input_", textRect
, resizeMask
, flags
),
40 _BTextInput_::_BTextInput_(BMessage
* archive
)
49 _BTextInput_::~_BTextInput_()
56 _BTextInput_::Instantiate(BMessage
* archive
)
58 if (validate_instantiation(archive
, "_BTextInput_"))
59 return new _BTextInput_(archive
);
66 _BTextInput_::Archive(BMessage
* data
, bool deep
) const
68 return BTextView::Archive(data
, true);
73 _BTextInput_::MouseDown(BPoint where
)
80 // only pass through to base class if we already have focus
81 BTextView::MouseDown(where
);
86 _BTextInput_::FrameResized(float width
, float height
)
88 BTextView::FrameResized(width
, height
);
95 _BTextInput_::KeyDown(const char* bytes
, int32 numBytes
)
100 if (!TextControl()->IsEnabled())
103 if (fPreviousText
== NULL
|| strcmp(Text(), fPreviousText
) != 0) {
104 TextControl()->Invoke();
106 fPreviousText
= strdup(Text());
114 BView::KeyDown(bytes
, numBytes
);
118 BTextView::KeyDown(bytes
, numBytes
);
126 _BTextInput_::MakeFocus(bool state
)
128 if (state
== IsFocus())
131 BTextView::MakeFocus(state
);
137 if (strcmp(Text(), fPreviousText
) != 0)
138 TextControl()->Invoke();
141 fPreviousText
= NULL
;
144 if (Window() != NULL
) {
145 // Invalidate parent to draw or remove the focus mark
146 if (BTextControl
* parent
= dynamic_cast<BTextControl
*>(Parent())) {
147 BRect frame
= Frame();
148 frame
.InsetBy(-1.0, -1.0);
149 parent
->Invalidate(frame
);
156 _BTextInput_::MinSize()
159 min
.height
= ceilf(LineHeight(0) + 2.0);
160 // we always add at least one pixel vertical inset top/bottom for
162 min
.width
= min
.height
* 3;
163 return BLayoutUtils::ComposeSize(ExplicitMinSize(), min
);
168 _BTextInput_::AlignTextRect()
170 // the label font could require the control to be higher than
171 // necessary for the text view, we compensate this by layouting
172 // the text rect to be in the middle, normally this means there
173 // is one pixel spacing on each side
174 BRect
textRect(Bounds());
175 float vInset
= max_c(1,
176 floorf((textRect
.Height() - LineHeight(0)) / 2.0));
178 float textFontWidth
= TextRect().Width();
180 switch (Alignment()) {
182 hInset
= be_control_look
->DefaultLabelSpacing();
186 hInset
= textRect
.Width() - textFontWidth
;
187 hInset
-= be_control_look
->DefaultLabelSpacing();
191 hInset
= (textRect
.Width() - textFontWidth
) / 2.0;
198 textRect
.InsetBy(hInset
, vInset
);
199 SetTextRect(textRect
);
204 _BTextInput_::SetInitialText()
207 fPreviousText
= NULL
;
210 fPreviousText
= strdup(Text());
215 _BTextInput_::Paste(BClipboard
* clipboard
)
217 BTextView::Paste(clipboard
);
223 _BTextInput_::InsertText(const char* inText
, int32 inLength
,
224 int32 inOffset
, const text_run_array
* inRuns
)
226 // Filter all line breaks, note that inText is not terminated.
228 if (*inText
== '\n' || *inText
== '\r')
229 BTextView::InsertText(" ", 1, inOffset
, inRuns
);
231 BTextView::InsertText(inText
, 1, inOffset
, inRuns
);
233 BString
filteredText(inText
, inLength
);
234 filteredText
.ReplaceAll('\n', ' ');
235 filteredText
.ReplaceAll('\r', ' ');
236 BTextView::InsertText(filteredText
.String(), inLength
, inOffset
,
240 TextControl()->InvokeNotify(TextControl()->ModificationMessage(),
246 _BTextInput_::DeleteText(int32 fromOffset
, int32 toOffset
)
248 BTextView::DeleteText(fromOffset
, toOffset
);
250 TextControl()->InvokeNotify(TextControl()->ModificationMessage(),
256 _BTextInput_::TextControl()
258 BTextControl
* textControl
= NULL
;
259 if (Parent() != NULL
)
260 textControl
= dynamic_cast<BTextControl
*>(Parent());
262 if (textControl
== NULL
)
263 debugger("_BTextInput_ should have a BTextControl as parent");
269 } // namespace BPrivate