1/*
2 * Copyright 2006-2009, Stephan A��mus <superstippi@gmx.de>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
5
6#include "InputTextView.h"
7
8#include <stdio.h>
9#include <stdlib.h>
10
11#include <String.h>
12
13// constructor
14InputTextView::InputTextView(BRect frame, const char* name,
15							 BRect textRect,
16							 uint32 resizingMode,
17							 uint32 flags)
18	: BTextView(frame, name, textRect, resizingMode, flags),
19	  fWasFocus(false),
20	  fTextBeforeFocus("")
21{
22	SetWordWrap(false);
23}
24
25// destructor
26InputTextView::~InputTextView()
27{
28}
29
30// MouseDown
31void
32InputTextView::MouseDown(BPoint where)
33{
34	// enforce the behaviour of a typical BTextControl
35	// only let the BTextView handle mouse up/down when
36	// it already had focus
37	fWasFocus = IsFocus();
38	if (fWasFocus) {
39		BTextView::MouseDown(where);
40	} else {
41		// forward click
42		if (BView* view = Parent()) {
43			view->MouseDown(ConvertToParent(where));
44		}
45	}
46}
47
48// MouseUp
49void
50InputTextView::MouseUp(BPoint where)
51{
52	// enforce the behaviour of a typical BTextControl
53	// only let the BTextView handle mouse up/down when
54	// it already had focus
55	if (fWasFocus)
56		BTextView::MouseUp(where);
57}
58
59// KeyDown
60void
61InputTextView::KeyDown(const char* bytes, int32 numBytes)
62{
63	bool handled = true;
64	if (numBytes > 0) {
65		switch (bytes[0]) {
66			case B_ESCAPE:
67				// revert any typing changes
68				RevertChanges();
69				fTextBeforeFocus = Text();
70				break;
71			case B_RETURN:
72				ApplyChanges();
73				fTextBeforeFocus = Text();
74				break;
75			default:
76				handled = false;
77				break;
78		}
79	}
80	if (!handled)
81		BTextView::KeyDown(bytes, numBytes);
82}
83
84// MakeFocus
85void
86InputTextView::MakeFocus(bool focus)
87{
88	if (focus == IsFocus())
89		return;
90
91	if (BView* view = Parent())
92		view->Invalidate();
93	BTextView::MakeFocus(focus);
94	if (focus) {
95		SelectAll();
96		fTextBeforeFocus = Text();
97	} else {
98		// Only pressing ESC is supposed to revert to the previous
99		// value and not invoke, but in that case, the text will already
100		// be the previous value when we lose focus here.
101		if (fTextBeforeFocus != Text())
102			Invoke();
103	}
104}
105
106// Invoke
107status_t
108InputTextView::Invoke(BMessage* message)
109{
110	if (!message)
111		message = Message();
112
113	if (message) {
114		BMessage copy(*message);
115		copy.AddInt64("when", system_time());
116		copy.AddPointer("source", (BView*)this);
117		return BInvoker::Invoke(&copy);
118	}
119	return B_BAD_VALUE;
120}
121