libroot/posix/stdio: Remove unused portions.
[haiku.git] / src / preferences / touchpad / TouchpadPrefView.cpp
blobbe40878437a09fecaa4c492aff9b5b7336f70463
1 /*
2 * Copyright 2008-2014 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * John Scipione, jscipione@gmail.com
7 * Clemens Zeidler, haiku@Clemens-Zeidler.de
8 */
11 #include "TouchpadPrefView.h"
13 #include <stdio.h>
15 #include <Alert.h>
16 #include <Box.h>
17 #include <Catalog.h>
18 #include <CheckBox.h>
19 #include <ControlLook.h>
20 #include <File.h>
21 #include <FindDirectory.h>
22 #include <Input.h>
23 #include <LayoutBuilder.h>
24 #include <Locale.h>
25 #include <MenuField.h>
26 #include <MenuItem.h>
27 #include <Message.h>
28 #include <Path.h>
29 #include <Screen.h>
30 #include <SpaceLayoutItem.h>
31 #include <Window.h>
33 #include <keyboard_mouse_driver.h>
36 const uint32 SCROLL_X_DRAG = 'sxdr';
37 const uint32 SCROLL_Y_DRAG = 'sydr';
39 #undef B_TRANSLATION_CONTEXT
40 #define B_TRANSLATION_CONTEXT "TouchpadPrefView"
43 TouchpadView::TouchpadView(BRect frame)
45 BView(frame, "TouchpadView", B_FOLLOW_NONE, B_WILL_DRAW)
47 fXTracking = false;
48 fYTracking = false;
49 fOffScreenView = NULL;
50 fOffScreenBitmap = NULL;
52 fPrefRect = frame;
53 fPadRect = fPrefRect;
54 fPadRect.InsetBy(10, 10);
55 fXScrollRange = fPadRect.Width();
56 fYScrollRange = fPadRect.Height();
61 TouchpadView::~TouchpadView()
63 delete fOffScreenBitmap;
67 void
68 TouchpadView::Draw(BRect updateRect)
70 DrawSliders();
74 void
75 TouchpadView::MouseDown(BPoint point)
77 if (fXScrollDragZone.Contains(point)) {
78 fXTracking = true;
79 fOldXScrollRange = fXScrollRange;
80 SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
83 if (fYScrollDragZone.Contains(point)) {
84 fYTracking = true;
85 fOldYScrollRange = fYScrollRange;
86 SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
91 void
92 TouchpadView::MouseUp(BPoint point)
94 if (!fXTracking && !fYTracking)
95 return;
97 fXTracking = false;
98 fYTracking = false;
100 const float kSoftScrollLimit = 0.7;
102 int32 result = 0;
103 if (GetRightScrollRatio() > kSoftScrollLimit
104 || GetBottomScrollRatio() > kSoftScrollLimit) {
105 BAlert* alert = new BAlert(B_TRANSLATE("Please confirm"),
106 B_TRANSLATE("The new scroll area is very large and may impede "
107 "normal mouse operation. Do you really want to change it?"),
108 B_TRANSLATE("OK"), B_TRANSLATE("Cancel"),
109 NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
110 alert->SetShortcut(1, B_ESCAPE);
111 result = alert->Go();
114 if (result == 0) {
115 BMessage msg(SCROLL_AREA_CHANGED);
116 Invoke(&msg);
117 } else {
118 if (GetRightScrollRatio() > kSoftScrollLimit)
119 fXScrollRange = fOldXScrollRange;
120 if (GetBottomScrollRatio() > kSoftScrollLimit)
121 fYScrollRange = fOldYScrollRange;
122 DrawSliders();
127 void
128 TouchpadView::AttachedToWindow()
130 if (!fOffScreenView)
131 fOffScreenView = new BView(Bounds(), "", B_FOLLOW_ALL, B_WILL_DRAW);
133 if (!fOffScreenBitmap) {
134 fOffScreenBitmap = new BBitmap(Bounds(), B_CMAP8, true, false);
136 if (fOffScreenBitmap && fOffScreenView)
137 fOffScreenBitmap->AddChild(fOffScreenView);
142 void
143 TouchpadView::SetValues(float rightRange, float bottomRange)
145 fXScrollRange = fPadRect.Width() * (1 - rightRange);
146 fYScrollRange = fPadRect.Height() * (1 - bottomRange);
147 Invalidate();
151 void
152 TouchpadView::GetPreferredSize(float* width, float* height)
154 if (width != NULL)
155 *width = fPrefRect.Width();
156 if (height != NULL)
157 *height = fPrefRect.Height();
161 void
162 TouchpadView::MouseMoved(BPoint point, uint32 transit, const BMessage* message)
164 if (fXTracking) {
165 if (point.x > fPadRect.right)
166 fXScrollRange = fPadRect.Width();
167 else if (point.x < fPadRect.left)
168 fXScrollRange = 0;
169 else
170 fXScrollRange = point.x - fPadRect.left;
172 DrawSliders();
175 if (fYTracking) {
176 if (point.y > fPadRect.bottom)
177 fYScrollRange = fPadRect.Height();
178 else if (point.y < fPadRect.top)
179 fYScrollRange = 0;
180 else
181 fYScrollRange = point.y - fPadRect.top;
183 DrawSliders();
189 void
190 TouchpadView::DrawSliders()
192 BView* view = fOffScreenView != NULL ? fOffScreenView : this;
194 if (!LockLooper())
195 return;
197 if (fOffScreenBitmap->Lock()) {
198 view->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
199 view->FillRect(Bounds());
200 view->SetHighColor(100, 100, 100);
201 view->FillRoundRect(fPadRect, 4, 4);
203 int32 dragSize = 3; // half drag size
205 // scroll areas
206 view->SetHighColor(145, 100, 100);
207 BRect rightRect(fPadRect.left + fXScrollRange, fPadRect.top,
208 fPadRect.right, fPadRect.bottom);
209 view->FillRoundRect(rightRect, 4, 4);
211 BRect bottomRect(fPadRect.left, fPadRect.top + fYScrollRange,
212 fPadRect.right, fPadRect.bottom);
213 view->FillRoundRect(bottomRect, 4, 4);
215 // Stroke Rect
216 view->SetHighColor(100, 100, 100);
217 view->SetPenSize(2);
218 view->StrokeRoundRect(fPadRect, 4, 4);
220 // x scroll range line
221 view->SetHighColor(200, 0, 0);
222 view->StrokeLine(BPoint(fPadRect.left + fXScrollRange, fPadRect.top),
223 BPoint(fPadRect.left + fXScrollRange, fPadRect.bottom));
225 fXScrollDragZone = BRect(fPadRect.left + fXScrollRange - dragSize,
226 fPadRect.top - dragSize, fPadRect.left + fXScrollRange + dragSize,
227 fPadRect.bottom + dragSize);
228 fXScrollDragZone1 = BRect(fPadRect.left + fXScrollRange - dragSize,
229 fPadRect.top - dragSize, fPadRect.left + fXScrollRange + dragSize,
230 fPadRect.top + dragSize);
231 view->FillRect(fXScrollDragZone1);
232 fXScrollDragZone2 = BRect(fPadRect.left + fXScrollRange - dragSize,
233 fPadRect.bottom - dragSize,
234 fPadRect.left + fXScrollRange + dragSize,
235 fPadRect.bottom + dragSize);
236 view->FillRect(fXScrollDragZone2);
238 // y scroll range line
239 view->StrokeLine(BPoint(fPadRect.left, fPadRect.top + fYScrollRange),
240 BPoint(fPadRect.right, fPadRect.top + fYScrollRange));
242 fYScrollDragZone = BRect(fPadRect.left - dragSize,
243 fPadRect.top + fYScrollRange - dragSize,
244 fPadRect.right + dragSize,
245 fPadRect.top + fYScrollRange + dragSize);
246 fYScrollDragZone1 = BRect(fPadRect.left - dragSize,
247 fPadRect.top + fYScrollRange - dragSize, fPadRect.left + dragSize,
248 fPadRect.top + fYScrollRange + dragSize);
249 view->FillRect(fYScrollDragZone1);
250 fYScrollDragZone2 = BRect(fPadRect.right - dragSize,
251 fPadRect.top + fYScrollRange - dragSize, fPadRect.right + dragSize,
252 fPadRect.top + fYScrollRange + dragSize);
253 view->FillRect(fYScrollDragZone2);
255 view->Sync();
256 fOffScreenBitmap->Unlock();
257 DrawBitmap(fOffScreenBitmap, B_ORIGIN);
260 UnlockLooper();
264 // #pragma mark - TouchpadPrefView
267 TouchpadPrefView::TouchpadPrefView()
269 BGroupView()
271 SetupView();
272 // set view values
273 SetValues(&fTouchpadPref.Settings());
277 TouchpadPrefView::~TouchpadPrefView()
282 void
283 TouchpadPrefView::MessageReceived(BMessage* message)
285 touchpad_settings& settings = fTouchpadPref.Settings();
287 switch (message->what) {
288 case SCROLL_AREA_CHANGED:
289 settings.scroll_rightrange = fTouchpadView->GetRightScrollRatio();
290 settings.scroll_bottomrange = fTouchpadView->GetBottomScrollRatio();
291 fRevertButton->SetEnabled(true);
292 fTouchpadPref.UpdateSettings();
293 break;
295 case SCROLL_CONTROL_CHANGED:
296 settings.scroll_twofinger = fTwoFingerBox->Value() == B_CONTROL_ON;
297 settings.scroll_twofinger_horizontal
298 = fTwoFingerHorizontalBox->Value() == B_CONTROL_ON;
299 settings.scroll_acceleration = fScrollAccelSlider->Value();
300 settings.scroll_xstepsize = (20 - fScrollStepXSlider->Value()) * 3;
301 settings.scroll_ystepsize = (20 - fScrollStepYSlider->Value()) * 3;
302 fRevertButton->SetEnabled(true);
303 fTwoFingerHorizontalBox->SetEnabled(settings.scroll_twofinger);
304 fTouchpadPref.UpdateSettings();
305 break;
307 case TAP_CONTROL_CHANGED:
308 settings.tapgesture_sensibility = fTapSlider->Value();
309 fRevertButton->SetEnabled(true);
310 fTouchpadPref.UpdateSettings();
311 break;
313 case DEFAULT_SETTINGS:
314 fTouchpadPref.Defaults();
315 fRevertButton->SetEnabled(true);
316 fTouchpadPref.UpdateSettings();
317 SetValues(&settings);
318 break;
320 case REVERT_SETTINGS:
321 fTouchpadPref.Revert();
322 fTouchpadPref.UpdateSettings();
323 fRevertButton->SetEnabled(false);
324 SetValues(&settings);
325 break;
327 default:
328 BView::MessageReceived(message);
333 void
334 TouchpadPrefView::AttachedToWindow()
336 fTouchpadView->SetTarget(this);
337 fTwoFingerBox->SetTarget(this);
338 fTwoFingerHorizontalBox->SetTarget(this);
339 fScrollStepXSlider->SetTarget(this);
340 fScrollStepYSlider->SetTarget(this);
341 fScrollAccelSlider->SetTarget(this);
342 fTapSlider->SetTarget(this);
343 fDefaultButton->SetTarget(this);
344 fRevertButton->SetTarget(this);
345 BSize size = PreferredSize();
346 Window()->ResizeTo(size.width, size.height);
348 BPoint position = fTouchpadPref.WindowPosition();
349 // center window on screen if it had a bad position
350 if (position.x < 0 && position.y < 0)
351 Window()->CenterOnScreen();
352 else
353 Window()->MoveTo(position);
357 void
358 TouchpadPrefView::DetachedFromWindow()
360 fTouchpadPref.SetWindowPosition(Window()->Frame().LeftTop());
364 void
365 TouchpadPrefView::SetupView()
367 SetLayout(new BGroupLayout(B_VERTICAL));
368 BBox* scrollBox = new BBox("Touchpad");
369 scrollBox->SetLabel(B_TRANSLATE("Scrolling"));
371 fTouchpadView = new TouchpadView(BRect(0, 0, 130, 120));
372 fTouchpadView->SetExplicitMaxSize(BSize(130, 120));
374 // Create the "Mouse Speed" slider...
375 fScrollAccelSlider = new BSlider("scroll_accel",
376 B_TRANSLATE("Acceleration"),
377 new BMessage(SCROLL_CONTROL_CHANGED), 0, 20, B_HORIZONTAL);
378 fScrollAccelSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
379 fScrollAccelSlider->SetHashMarkCount(7);
380 fScrollAccelSlider->SetLimitLabels(B_TRANSLATE("Slow"),
381 B_TRANSLATE("Fast"));
382 fScrollAccelSlider->SetExplicitMinSize(BSize(150, B_SIZE_UNSET));
384 fScrollStepXSlider = new BSlider("scroll_stepX",
385 B_TRANSLATE("Horizontal"),
386 new BMessage(SCROLL_CONTROL_CHANGED),
387 0, 20, B_HORIZONTAL);
388 fScrollStepXSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
389 fScrollStepXSlider->SetHashMarkCount(7);
390 fScrollStepXSlider->SetLimitLabels(B_TRANSLATE("Slow"),
391 B_TRANSLATE("Fast"));
393 fScrollStepYSlider = new BSlider("scroll_stepY",
394 B_TRANSLATE("Vertical"),
395 new BMessage(SCROLL_CONTROL_CHANGED), 0, 20, B_HORIZONTAL);
396 fScrollStepYSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
397 fScrollStepYSlider->SetHashMarkCount(7);
398 fScrollStepYSlider->SetLimitLabels(B_TRANSLATE("Slow"),
399 B_TRANSLATE("Fast"));
401 fTwoFingerBox = new BCheckBox(B_TRANSLATE("Two finger scrolling"),
402 new BMessage(SCROLL_CONTROL_CHANGED));
403 fTwoFingerHorizontalBox = new BCheckBox(
404 B_TRANSLATE("Horizontal scrolling"),
405 new BMessage(SCROLL_CONTROL_CHANGED));
407 float spacing = be_control_look->DefaultItemSpacing();
409 BView* scrollPrefLeftLayout
410 = BLayoutBuilder::Group<>(B_VERTICAL, 0)
411 .Add(fTouchpadView)
412 .AddStrut(spacing)
413 .Add(fTwoFingerBox)
414 .AddGroup(B_HORIZONTAL, 0)
415 .AddStrut(spacing * 2)
416 .Add(fTwoFingerHorizontalBox)
417 .End()
418 .AddGlue()
419 .View();
421 BGroupView* scrollPrefRightLayout = new BGroupView(B_VERTICAL);
422 scrollPrefRightLayout->AddChild(fScrollAccelSlider);
423 scrollPrefRightLayout->AddChild(fScrollStepXSlider);
424 scrollPrefRightLayout->AddChild(fScrollStepYSlider);
426 BGroupLayout* scrollPrefLayout = new BGroupLayout(B_HORIZONTAL);
427 scrollPrefLayout->SetSpacing(spacing);
428 scrollPrefLayout->SetInsets(spacing,
429 scrollBox->TopBorderOffset() * 2 + spacing, spacing, spacing);
430 scrollBox->SetLayout(scrollPrefLayout);
432 scrollPrefLayout->AddView(scrollPrefLeftLayout);
433 scrollPrefLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(spacing
434 * 1.5));
435 scrollPrefLayout->AddView(scrollPrefRightLayout);
437 BBox* tapBox = new BBox("tapbox");
438 tapBox->SetLabel(B_TRANSLATE("Tapping"));
440 BGroupLayout* tapPrefLayout = new BGroupLayout(B_HORIZONTAL);
441 tapPrefLayout->SetInsets(spacing, tapBox->TopBorderOffset() * 2 + spacing,
442 spacing, spacing);
443 tapBox->SetLayout(tapPrefLayout);
445 fTapSlider = new BSlider("tap_sens", B_TRANSLATE("Sensitivity"),
446 new BMessage(TAP_CONTROL_CHANGED), 0, spacing * 2, B_HORIZONTAL);
447 fTapSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
448 fTapSlider->SetHashMarkCount(7);
449 fTapSlider->SetLimitLabels(B_TRANSLATE("Off"), B_TRANSLATE("High"));
451 tapPrefLayout->AddView(fTapSlider);
453 fDefaultButton = new BButton(B_TRANSLATE("Defaults"),
454 new BMessage(DEFAULT_SETTINGS));
456 fRevertButton = new BButton(B_TRANSLATE("Revert"),
457 new BMessage(REVERT_SETTINGS));
458 fRevertButton->SetEnabled(false);
460 BLayoutBuilder::Group<>(this, B_VERTICAL)
461 .SetInsets(B_USE_WINDOW_SPACING)
462 .Add(scrollBox)
463 .Add(tapBox)
464 .AddGroup(B_HORIZONTAL)
465 .Add(fDefaultButton)
466 .Add(fRevertButton)
467 .AddGlue()
468 .End()
469 .End();
473 void
474 TouchpadPrefView::SetValues(touchpad_settings* settings)
476 fTouchpadView->SetValues(settings->scroll_rightrange,
477 settings->scroll_bottomrange);
478 fTwoFingerBox->SetValue(settings->scroll_twofinger
479 ? B_CONTROL_ON : B_CONTROL_OFF);
480 fTwoFingerHorizontalBox->SetValue(settings->scroll_twofinger_horizontal
481 ? B_CONTROL_ON : B_CONTROL_OFF);
482 fTwoFingerHorizontalBox->SetEnabled(settings->scroll_twofinger);
483 fScrollStepXSlider->SetValue(20 - settings->scroll_xstepsize / 2);
484 fScrollStepYSlider->SetValue(20 - settings->scroll_ystepsize / 2);
485 fScrollAccelSlider->SetValue(settings->scroll_acceleration);
486 fTapSlider->SetValue(settings->tapgesture_sensibility);