xref: /haiku/src/preferences/input/SettingsView.cpp (revision a127b88ecbfab58f64944c98aa47722a18e363b2)
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 <Bitmap.h>
13 #include <Box.h>
14 #include <Button.h>
15 #include <Catalog.h>
16 #include <ControlLook.h>
17 #include <Debug.h>
18 #include <InterfaceDefs.h>
19 #include <LayoutBuilder.h>
20 #include <Locale.h>
21 #include <MenuField.h>
22 #include <MenuItem.h>
23 #include <PopUpMenu.h>
24 #include <SeparatorView.h>
25 #include <Slider.h>
26 #include <TextControl.h>
27 #include <TranslationUtils.h>
28 #include <Window.h>
29 
30 #include "InputConstants.h"
31 #include "MouseSettings.h"
32 #include "MouseView.h"
33 
34 
35 //	#pragma mark -
36 
37 #undef B_TRANSLATION_CONTEXT
38 #define B_TRANSLATION_CONTEXT "SettingsView"
39 
40 
41 SettingsView::SettingsView(MouseSettings& settings)
42 	:
43 	BBox("main_view"),
44 	fSettings(settings)
45 {
46 	if (fSettings.MouseType() > 6)
47 		debugger("Mouse type is invalid");
48 
49 	// Add the "Mouse Type" pop up menu
50 	fTypeMenu = new BOptionPopUp(
51 		"type", B_TRANSLATE("Mouse type:"), new BMessage(kMsgMouseType));
52 	fTypeMenu->AddOption(B_TRANSLATE("1-Button"), 1);
53 	fTypeMenu->AddOption(B_TRANSLATE("2-Button"), 2);
54 	fTypeMenu->AddOption(B_TRANSLATE("3-Button"), 3);
55 	fTypeMenu->AddOption(B_TRANSLATE("4-Button"), 4);
56 	fTypeMenu->AddOption(B_TRANSLATE("5-Button"), 5);
57 	fTypeMenu->AddOption(B_TRANSLATE("6-Button"), 6);
58 
59 	// Create the "Double-click speed slider...
60 	fClickSpeedSlider
61 		= new BSlider("double_click_speed", B_TRANSLATE("Double-click speed"),
62 			new BMessage(kMsgDoubleClickSpeed), 0, 1000, B_HORIZONTAL);
63 	fClickSpeedSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
64 	fClickSpeedSlider->SetHashMarkCount(7);
65 
66 	// Create the "Mouse Speed" slider...
67 	fMouseSpeedSlider = new BSlider("mouse_speed", B_TRANSLATE("Mouse speed"),
68 		new BMessage(kMsgMouseSpeed), 0, 1000, B_HORIZONTAL);
69 	fMouseSpeedSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
70 	fMouseSpeedSlider->SetHashMarkCount(7);
71 
72 	// Create the "Mouse Acceleration" slider...
73 	fAccelerationSlider
74 		= new BSlider("mouse_acceleration", B_TRANSLATE("Mouse acceleration"),
75 			new BMessage(kMsgAccelerationFactor), 0, 1000, B_HORIZONTAL);
76 	fAccelerationSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
77 	fAccelerationSlider->SetHashMarkCount(7);
78 
79 	fMouseView = new MouseView(fSettings);
80 
81 	// Create the "Double-click test area" text box...
82 	const char* label = B_TRANSLATE("Double-click test area");
83 	BTextControl* doubleClickTextControl = new BTextControl(NULL, label, NULL);
84 	doubleClickTextControl->SetAlignment(B_ALIGN_LEFT, B_ALIGN_CENTER);
85 	doubleClickTextControl->SetExplicitMinSize(
86 		BSize(StringWidth(label), B_SIZE_UNSET));
87 
88 	// Add the "Mouse focus mode" pop up menu
89 	fFocusMenu = new BOptionPopUp("focus_mode", B_TRANSLATE("Focus mode:"),
90 		new BMessage(kMsgMouseFocusMode));
91 
92 	const char* focusLabels[] = {B_TRANSLATE_MARK("Click to focus and raise"),
93 		B_TRANSLATE_MARK("Click to focus"),
94 		B_TRANSLATE_MARK("Focus follows mouse")};
95 	const mode_mouse focusModes[]
96 		= {B_NORMAL_MOUSE, B_CLICK_TO_FOCUS_MOUSE, B_FOCUS_FOLLOWS_MOUSE};
97 
98 	for (size_t i = 0; i < B_COUNT_OF(focusModes); i++)
99 		fFocusMenu->AddOption(
100 			B_TRANSLATE_NOCOLLECT(focusLabels[i]), focusModes[i]);
101 
102 	// Add the "Click-through" check box
103 	fAcceptFirstClickBox = new BCheckBox(
104 		B_TRANSLATE("Accept first click"), new BMessage(kMsgAcceptFirstClick));
105 
106 	// Build the layout
107 
108 	// Layout is :
109 	// A | B
110 	// -----
111 	//   C
112 
113 	BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
114 		// Horizontal : A|B
115 		.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
116 
117 			// Vertical block A: mouse type/view/test
118 			.AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING)
119 				.Add(fTypeMenu)
120 				.AddGroup(B_HORIZONTAL, 0)
121 					.AddGlue()
122 					.Add(fMouseView)
123 					.AddGlue()
124 					.End()
125 				.AddGlue()
126 				.Add(doubleClickTextControl)
127 				.End()
128 			.Add(new BSeparatorView(B_VERTICAL))
129 
130 			// Vertical block B: speed settings
131 			.AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING, 3)
132 				.AddGroup(B_HORIZONTAL, 0)
133 					.Add(fClickSpeedSlider)
134 					.End()
135 				.AddGroup(B_HORIZONTAL, 0)
136 					.Add(fMouseSpeedSlider)
137 					.End()
138 				.AddGroup(B_HORIZONTAL, 0)
139 					.Add(fAccelerationSlider)
140 					.End()
141 				.End()
142 			.End()
143 		.AddStrut(B_USE_DEFAULT_SPACING)
144 
145 		// Horizontal Block C: focus mode
146 		.AddGroup(B_HORIZONTAL, B_USE_SMALL_SPACING)
147 			.Add(fFocusMenu)
148 			.AddGlue()
149 			.AddGroup(B_VERTICAL, 0)
150 				.Add(fAcceptFirstClickBox)
151 				.End()
152 			.End();
153 
154 	SetBorder(B_NO_BORDER);
155 }
156 
157 
158 SettingsView::~SettingsView()
159 {
160 }
161 
162 
163 void
164 SettingsView::AttachedToWindow()
165 {
166 	UpdateFromSettings();
167 }
168 
169 
170 void
171 SettingsView::SetMouseType(int32 type)
172 {
173 	if (type > 6)
174 		debugger("Mouse type is invalid");
175 	fMouseView->SetMouseType(type);
176 }
177 
178 
179 void
180 SettingsView::MouseMapUpdated()
181 {
182 	fMouseView->MouseMapUpdated();
183 }
184 
185 
186 void
187 SettingsView::UpdateFromSettings()
188 {
189 	int32 value = int32(fSettings.ClickSpeed() / 1000);
190 	// slow = 1000000, fast = 0
191 	fClickSpeedSlider->SetValue(value);
192 
193 	value = int32((log(fSettings.MouseSpeed() / 8192.0) / log(2)) * 1000 / 6);
194 	// slow = 8192, fast = 524287
195 	fMouseSpeedSlider->SetValue(value);
196 
197 	value = int32(sqrt(fSettings.AccelerationFactor() / 16384.0) * 1000 / 4);
198 	// slow = 0, fast = 262144
199 	fAccelerationSlider->SetValue(value);
200 
201 	fTypeMenu->SelectOptionFor(fSettings.MouseType());
202 	fMouseView->SetMouseType(fSettings.MouseType());
203 
204 	fFocusMenu->SelectOptionFor(fSettings.MouseMode());
205 
206 	fAcceptFirstClickBox->SetValue(
207 		fSettings.AcceptFirstClick() ? B_CONTROL_ON : B_CONTROL_OFF);
208 	fAcceptFirstClickBox->SetEnabled(
209 		fSettings.MouseMode() != B_FOCUS_FOLLOWS_MOUSE);
210 }
211