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 "InputSlider.h"
10
11#include <stdio.h>
12
13#include <Message.h>
14#include <MessageFilter.h>
15
16#include "NummericalTextView.h"
17
18
19// MouseDownFilter
20
21class NumericInputFilter : public BMessageFilter {
22 public:
23								NumericInputFilter(InputSlider* slider);
24
25	virtual	filter_result		Filter(BMessage*, BHandler** target);
26
27 private:
28			InputSlider*		fSlider;
29};
30
31// constructor
32NumericInputFilter::NumericInputFilter(InputSlider* slider)
33	: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
34	  fSlider(slider)
35{
36}
37
38// Filter
39filter_result
40NumericInputFilter::Filter(BMessage* msg, BHandler** target)
41{
42	filter_result result = B_DISPATCH_MESSAGE;
43	switch (msg->what)
44	{
45		case B_KEY_DOWN:
46		case B_KEY_UP:
47		{
48msg->PrintToStream();
49			const char *string;
50			if (msg->FindString("bytes", &string) == B_OK) {
51				while (*string != 0) {
52					if (*string < '0' || *string > '9') {
53
54						if (*string != '-') {
55							result = B_SKIP_MESSAGE;
56						}
57					}
58					string++;
59				}
60			}
61			break;
62		}
63		default:
64			break;
65	}
66	/*
67	if (fWindow) {
68		if (BView* view = dynamic_cast<BView*>(*target)) {
69			BPoint point;
70			if (message->FindPoint("where", &point) == B_OK) {
71				if (!fWindow->Frame().Contains(view->ConvertToScreen(point)))
72					*target = fWindow;
73			}
74		}
75	}*/
76	return result;
77}
78
79// constructor
80InputSlider::InputSlider(const char* name, const char* label,
81						 BMessage* model, BHandler* target,
82						 int32 min, int32 max, int32 value,
83						 const char* formatString)
84	: PopupSlider(name, label, model, target, min, max, value, formatString),
85	  fTextView(new NummericalTextView(BRect(0, 0 , 20, 20),
86	  								   "input",
87	  								   BRect(5, 5, 15, 15),
88	  								   B_FOLLOW_NONE,
89	  								   B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE))
90	  //fTextViewFilter(dynamic_cast<BMessageFilter*>(new NumericInputFilter(this)))
91{
92	// prepare fTextView
93	fTextView->SetWordWrap(false);
94	fTextView->SetViewColor(255,255,255,0);
95	fTextView->SetValue(Value());
96	//fTextView->AddFilter(fTextViewFilter);
97	AddChild(fTextView);
98}
99
100// destructor
101InputSlider::~InputSlider()
102{
103	//delete fTextViewFilter;
104}
105
106// layout
107BRect
108InputSlider::layout(BRect frame)
109{
110	PopupSlider::layout(frame);
111
112	frame = SliderFrame();
113
114	frame.right -= 10.0;
115	frame.InsetBy(2, 2);
116
117	fTextView->MoveTo(frame.LeftTop());
118	fTextView->ResizeTo(frame.Width(), frame.Height());
119
120	BRect textRect(fTextView->Bounds());
121	textRect.InsetBy(1, 1);
122	fTextView->SetTextRect(textRect);
123
124	fTextView->SetAlignment(B_ALIGN_CENTER);
125
126	return Frame();
127}
128
129// MouseDown
130void
131InputSlider::MouseDown(BPoint where)
132{
133	if (fTextView->Frame().Contains(where))
134		return;
135
136	fTextView->MakeFocus(true);
137
138	if (SliderFrame().Contains(where)) {
139		SetValue(fTextView->IntValue());
140		PopupSlider::MouseDown(where);
141	}
142}
143
144// SetEnabled
145void
146InputSlider::SetEnabled(bool enable)
147{
148	PopupSlider::SetEnabled(enable);
149
150//	fTextView->SetEnabled(enable);
151}
152
153// ValueChanged
154void
155InputSlider::ValueChanged(int32 newValue)
156{
157	PopupSlider::ValueChanged(newValue);
158
159	// change fTextView's value
160	if (LockLooper()) {
161		fTextView->SetValue(Value());
162		UnlockLooper();
163	}
164}
165
166// DrawSlider
167void
168InputSlider::DrawSlider(BRect frame, bool enabled)
169{
170	rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
171	rgb_color lightShadow;
172	rgb_color midShadow;
173	rgb_color darkShadow;
174	rgb_color light;
175	if (enabled) {
176		lightShadow = tint_color(background, B_DARKEN_1_TINT);
177		midShadow = tint_color(background, B_DARKEN_2_TINT);
178		darkShadow = tint_color(background, B_DARKEN_4_TINT);
179		light = tint_color(background, B_LIGHTEN_MAX_TINT);
180	} else {
181		lightShadow = background;
182		midShadow = tint_color(background, B_DARKEN_1_TINT);
183		darkShadow = tint_color(background, B_DARKEN_2_TINT);
184		light = tint_color(background, B_LIGHTEN_1_TINT);
185	}
186
187	// frame around text view
188	BRect r(frame);
189	BeginLineArray(16);
190		AddLine(BPoint(r.left, r.bottom),
191				BPoint(r.left, r.top), lightShadow);
192		AddLine(BPoint(r.left + 1.0, r.top),
193				BPoint(r.right, r.top), lightShadow);
194		AddLine(BPoint(r.right, r.top + 1.0),
195				BPoint(r.right, r.bottom), light);
196		AddLine(BPoint(r.right - 1.0, r.bottom),
197				BPoint(r.left + 1.0, r.bottom), light);
198
199		r = fTextView->Frame().InsetByCopy(-1, -1);
200
201		AddLine(BPoint(r.left, r.bottom),
202				BPoint(r.left, r.top), darkShadow);
203		AddLine(BPoint(r.left + 1.0, r.top),
204				BPoint(r.right, r.top), darkShadow);
205		AddLine(BPoint(r.right, r.top + 1.0),
206				BPoint(r.right, r.bottom), background);
207		AddLine(BPoint(r.right - 1.0, r.bottom),
208				BPoint(r.left + 1.0, r.bottom), background);
209
210		r.left = r.right + 1;
211		r.right = frame.right - 1;
212
213		AddLine(BPoint(r.left, r.bottom),
214				BPoint(r.left, r.top + 1.0), midShadow);
215		AddLine(BPoint(r.left, r.top),
216				BPoint(r.right, r.top), darkShadow);
217		AddLine(BPoint(r.right, r.top + 1.0),
218				BPoint(r.right, r.bottom), midShadow);
219		AddLine(BPoint(r.right - 1.0, r.bottom),
220				BPoint(r.left + 1.0, r.bottom), midShadow);
221
222		r.InsetBy(1, 1);
223
224		AddLine(BPoint(r.left, r.bottom),
225				BPoint(r.left, r.top), light);
226		AddLine(BPoint(r.left + 1.0, r.top),
227				BPoint(r.right, r.top), light);
228		AddLine(BPoint(r.right, r.top + 1.0),
229				BPoint(r.right, r.bottom), lightShadow);
230		AddLine(BPoint(r.right - 1.0, r.bottom),
231				BPoint(r.left + 1.0, r.bottom), lightShadow);
232	EndLineArray();
233
234	r.InsetBy(1, 1);
235	SetLowColor(background);
236	FillRect(r, B_SOLID_LOW);
237}
238
239