xref: /haiku/src/preferences/input/InputWindow.cpp (revision 7a617f59fd64449167bb190666bd44fae7efbe0b)
1 /*
2  * Copyright 2019-2020, Haiku, Inc.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Preetpal Kaur <preetpalok123@gmail.com>
7  *		Adrien Destugues <pulkomandy@gmail.com>
8  */
9 
10 
11 #include <Alert.h>
12 #include <Alignment.h>
13 #include <Application.h>
14 #include <Button.h>
15 #include <CardLayout.h>
16 #include <CardView.h>
17 #include <Catalog.h>
18 #include <Control.h>
19 #include <ControlLook.h>
20 #include <LayoutBuilder.h>
21 #include <SplitView.h>
22 #include <Screen.h>
23 
24 #include <private/input/InputServerTypes.h>
25 
26 #include "InputConstants.h"
27 #include "InputDeviceView.h"
28 #include "InputMouse.h"
29 #include "InputTouchpadPref.h"
30 #include "InputWindow.h"
31 #include "MouseSettings.h"
32 #include "SettingsView.h"
33 
34 #undef B_TRANSLATION_CONTEXT
35 #define B_TRANSLATION_CONTEXT "InputWindow"
36 
37 
38 InputWindow::InputWindow(BRect rect)
39 	:
40 	BWindow(rect, B_TRANSLATE_SYSTEM_NAME("Input"), B_TITLED_WINDOW,
41 		B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS
42 		| B_AUTO_UPDATE_SIZE_LIMITS | B_QUIT_ON_WINDOW_CLOSE)
43 {
44 	FindDevice();
45 
46 	BLayoutBuilder::Group<>(this, B_HORIZONTAL, 10)
47 		.SetInsets(B_USE_WINDOW_SPACING)
48 		.Add(fDeviceListView)
49 		.AddGroup(B_VERTICAL, 0)
50 			.Add(fCardView)
51 		.End();
52 }
53 
54 void
55 InputWindow::MessageReceived(BMessage* message)
56 {
57 	switch (message->what) {
58 		case ITEM_SELECTED:
59 		{
60 			int32 index = message->GetInt32("index", 0);
61 			if (index >= 0)
62 				fCardView->CardLayout()->SetVisibleItem(index);
63 			break;
64 		}
65 		case kMsgMouseType:
66 		case kMsgMouseMap:
67 		case kMsgMouseFocusMode:
68 		case kMsgFollowsMouseMode:
69 		case kMsgAcceptFirstClick:
70 		case kMsgDoubleClickSpeed:
71 		case kMsgMouseSpeed:
72 		case kMsgAccelerationFactor:
73 		case kMsgDefaults:
74 		case kMsgRevert:
75 		{
76 			PostMessage(message,
77 				fCardView->CardLayout()->VisibleItem()->View());
78 			break;
79 		}
80 		case SCROLL_AREA_CHANGED:
81 		case SCROLL_CONTROL_CHANGED:
82 		case TAP_CONTROL_CHANGED:
83 		case DEFAULT_SETTINGS:
84 		case REVERT_SETTINGS:
85 		{
86 			PostMessage(message,
87 				fCardView->CardLayout()->VisibleItem()->View());
88 			break;
89 		}
90 		case kMsgSliderrepeatrate:
91 		case kMsgSliderdelayrate:
92 		{
93 			PostMessage(message,
94 				fCardView->CardLayout()->VisibleItem()->View());
95 			break;
96 		}
97 
98 		case IS_NOTIFY_DEVICE:
99 		{
100 			bool added = message->FindBool("added");
101 			BString name = message->FindString("name");
102 
103 			if (added) {
104 				BInputDevice* device = find_input_device(name);
105 				if (device)
106 					AddDevice(device);
107 			} else {
108 				for (int i = 0; i < fDeviceListView->fDeviceList->CountItems();
109 					i++) {
110 					BStringItem* item = dynamic_cast<BStringItem*>(
111 						fDeviceListView->fDeviceList->ItemAt(i));
112 					if (item->Text() == name) {
113 						fDeviceListView->fDeviceList->RemoveItem(i);
114 						BView* settings = fCardView->ChildAt(i);
115 						fCardView->RemoveChild(settings);
116 						delete settings;
117 						break;
118 					}
119 				}
120 			}
121 
122 			break;
123 		}
124 
125 		default:
126 			BWindow::MessageReceived(message);
127 			break;
128 	}
129 }
130 
131 
132 void
133 InputWindow::Show()
134 {
135 	CenterOnScreen();
136 	BWindow::Show();
137 	watch_input_devices(this, true);
138 }
139 
140 
141 void
142 InputWindow::Hide()
143 {
144 	BWindow::Hide();
145 	watch_input_devices(this, false);
146 }
147 
148 
149 status_t
150 InputWindow::FindDevice()
151 {
152 	BList devList;
153 	status_t status = get_input_devices(&devList);
154 	if (status != B_OK)
155 		return status;
156 
157 	int32 i = 0;
158 
159 	fDeviceListView = new DeviceListView(B_TRANSLATE("Device List"));
160 	fCardView = new BCardView();
161 
162 	while (true) {
163 		BInputDevice* dev = (BInputDevice*)devList.ItemAt(i);
164 		if (dev == NULL) {
165 			break;
166 		}
167 		i++;
168 
169 		AddDevice(dev);
170 	}
171 
172 	return B_OK;
173 }
174 
175 
176 void
177 InputWindow::AddDevice(BInputDevice* dev)
178 {
179 	BString name = dev->Name();
180 
181 	if (dev->Type() == B_POINTING_DEVICE
182 		&& name.FindFirst("Touchpad") >= 0) {
183 
184 		TouchpadPrefView* view = new TouchpadPrefView(dev);
185 		fCardView->AddChild(view);
186 		fDeviceListView->fDeviceList->AddItem(new BStringItem(name));
187 	} else if (dev->Type() == B_POINTING_DEVICE) {
188 		InputMouse* view = new InputMouse(dev);
189 		fCardView->AddChild(view);
190 		fDeviceListView->fDeviceList->AddItem(new BStringItem(name));
191 	} else if (dev->Type() == B_KEYBOARD_DEVICE) {
192 		InputKeyboard* view = new InputKeyboard(dev);
193 		fCardView->AddChild(view);
194 		fDeviceListView->fDeviceList->AddItem(new BStringItem(name));
195 	} else {
196 		delete dev;
197 	}
198 }
199