1/*
2 * Copyright 2019, Haiku, Inc.
3 * Distributed under the terms of the MIT License.
4 *
5 * Author:
6 *		Preetpal Kaur <preetpalok123@gmail.com>
7 */
8
9
10#include "InputMouse.h"
11
12#include <Application.h>
13#include <Bitmap.h>
14#include <Box.h>
15#include <Button.h>
16#include <Catalog.h>
17#include <CheckBox.h>
18#include <ControlLook.h>
19#include <Debug.h>
20#include <LayoutBuilder.h>
21#include <Locale.h>
22#include <MenuField.h>
23#include <MenuItem.h>
24#include <PopUpMenu.h>
25#include <Screen.h>
26#include <Slider.h>
27#include <StringView.h>
28#include <TabView.h>
29
30#include "InputConstants.h"
31#include "InputWindow.h"
32#include "MouseSettings.h"
33#include "MouseView.h"
34
35
36#undef B_TRANSLATION_CONTEXT
37#define B_TRANSLATION_CONTEXT "InputMouse"
38
39
40InputMouse::InputMouse(BInputDevice* dev, MouseSettings* settings)
41	:
42	BView("InputMouse", B_WILL_DRAW)
43{
44	fSettings = settings;
45
46	fSettingsView = new SettingsView(*fSettings);
47
48	fDefaultsButton = new BButton(B_TRANSLATE("Defaults"),
49		new BMessage(kMsgDefaults));
50	fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
51
52	fRevertButton = new BButton(B_TRANSLATE("Revert"),
53		new BMessage(kMsgRevert));
54	fRevertButton->SetEnabled(false);
55
56	BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
57		.Add(fSettingsView)
58			.Add(new BSeparatorView(B_HORIZONTAL))
59				.AddGroup(B_HORIZONTAL)
60				.Add(fDefaultsButton)
61				.Add(fRevertButton)
62				.AddGlue()
63				.End()
64		.End();
65}
66
67
68InputMouse::~InputMouse()
69{
70}
71
72
73void
74InputMouse::MessageReceived(BMessage* message)
75{
76	switch (message->what) {
77		case kMsgDefaults:
78		{
79			fSettings->Defaults();
80			fSettingsView->UpdateFromSettings();
81
82			fDefaultsButton->SetEnabled(false);
83			fRevertButton->SetEnabled(fSettings->IsRevertable());
84			break;
85		}
86
87		case kMsgRevert:
88		{
89			fSettings->Revert();
90			fSettingsView->UpdateFromSettings();
91
92			fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
93			fRevertButton->SetEnabled(false);
94			break;
95		}
96
97		case kMsgMouseType:
98		{
99			int32 type;
100			if (message->FindInt32("be:value", &type) == B_OK) {
101				if (type > 6)
102					debugger("Mouse type is invalid");
103				fSettings->SetMouseType(type);
104				fSettingsView->SetMouseType(type);
105				fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
106				fRevertButton->SetEnabled(fSettings->IsRevertable());
107			}
108			break;
109		}
110
111		case kMsgMouseFocusMode:
112		{
113			int32 mode;
114			if (message->FindInt32("be:value", &mode) == B_OK) {
115				fSettings->SetMouseMode((mode_mouse)mode);
116				fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
117				fRevertButton->SetEnabled(fSettings->IsRevertable());
118				fSettingsView->fAcceptFirstClickBox->SetEnabled(
119					mode != B_FOCUS_FOLLOWS_MOUSE);
120			}
121			break;
122		}
123
124		case kMsgFollowsMouseMode:
125		{
126			int32 mode;
127			if (message->FindInt32("mode_focus_follows_mouse", &mode) == B_OK) {
128				fSettings->SetFocusFollowsMouseMode(
129					(mode_focus_follows_mouse)mode);
130				fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
131				fRevertButton->SetEnabled(fSettings->IsRevertable());
132			}
133			break;
134		}
135
136		case kMsgAcceptFirstClick:
137		{
138			BHandler* handler;
139			if (message->FindPointer(
140					"source", reinterpret_cast<void**>(&handler))
141				== B_OK) {
142				bool acceptFirstClick = true;
143				BCheckBox* acceptFirstClickBox
144					= dynamic_cast<BCheckBox*>(handler);
145				if (acceptFirstClickBox)
146					acceptFirstClick
147						= acceptFirstClickBox->Value() == B_CONTROL_ON;
148				fSettings->SetAcceptFirstClick(acceptFirstClick);
149				fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
150				fRevertButton->SetEnabled(fSettings->IsRevertable());
151			}
152			break;
153		}
154
155		case kMsgDoubleClickSpeed:
156		{
157			int32 value;
158			if (message->FindInt32("be:value", &value) == B_OK) {
159				// slow = 1000000, fast = 0
160				fSettings->SetClickSpeed(value * 1000);
161				fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
162				fRevertButton->SetEnabled(fSettings->IsRevertable());
163			}
164			break;
165		}
166
167		case kMsgMouseSpeed:
168		{
169			int32 value;
170			if (message->FindInt32("be:value", &value) == B_OK) {
171				// slow = 8192, fast = 524287
172				fSettings->SetMouseSpeed(
173					(int32)pow(2, value * 6.0 / 1000) * 8192);
174				fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
175				fRevertButton->SetEnabled(fSettings->IsRevertable());
176			}
177			break;
178		}
179
180		case kMsgAccelerationFactor:
181		{
182			int32 value;
183			if (message->FindInt32("be:value", &value) == B_OK) {
184				// slow = 0, fast = 262144
185				fSettings->SetAccelerationFactor(
186					(int32)pow(value * 4.0 / 1000, 2) * 16384);
187				fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
188				fRevertButton->SetEnabled(fSettings->IsRevertable());
189			}
190			break;
191		}
192
193		case kMsgMouseMap:
194		{
195			int32 index;
196			int32 button;
197			if (message->FindInt32("index", &index) == B_OK
198				&& message->FindInt32("button", &button) == B_OK) {
199				int32 mapping = B_MOUSE_BUTTON(index + 1);
200				fSettings->SetMapping(button, mapping);
201				fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
202				fRevertButton->SetEnabled(fSettings->IsRevertable());
203				fSettingsView->MouseMapUpdated();
204			}
205			break;
206		}
207
208		default:
209			BView::MessageReceived(message);
210	}
211}
212