fat: Greatly simplify and clean up dosfs_get_file_map().
[haiku.git] / src / preferences / touchpad / TouchpadPrefView.cpp
blob7a93a5796f6d9598353c4dbfc81e05e656aeb7b2
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 puts("GONE!");
64 delete fOffScreenBitmap;
68 void
69 TouchpadView::Draw(BRect updateRect)
71 DrawSliders();
75 void
76 TouchpadView::MouseDown(BPoint point)
78 if (fXScrollDragZone.Contains(point)) {
79 fXTracking = true;
80 fOldXScrollRange = fXScrollRange;
81 SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
84 if (fYScrollDragZone.Contains(point)) {
85 fYTracking = true;
86 fOldYScrollRange = fYScrollRange;
87 SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
92 void
93 TouchpadView::MouseUp(BPoint point)
95 if (!fXTracking && !fYTracking)
96 return;
98 fXTracking = false;
99 fYTracking = false;
101 const float kSoftScrollLimit = 0.7;
103 int32 result = 0;
104 if (GetRightScrollRatio() > kSoftScrollLimit
105 || GetBottomScrollRatio() > kSoftScrollLimit) {
106 BAlert* alert = new BAlert(B_TRANSLATE("Please confirm"),
107 B_TRANSLATE("The new scroll area is very large and may impede "
108 "normal mouse operation. Do you really want to change it?"),
109 B_TRANSLATE("OK"), B_TRANSLATE("Cancel"),
110 NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
111 alert->SetShortcut(1, B_ESCAPE);
112 result = alert->Go();
115 if (result == 0) {
116 BMessage msg(SCROLL_AREA_CHANGED);
117 Invoke(&msg);
118 } else {
119 if (GetRightScrollRatio() > kSoftScrollLimit)
120 fXScrollRange = fOldXScrollRange;
121 if (GetBottomScrollRatio() > kSoftScrollLimit)
122 fYScrollRange = fOldYScrollRange;
123 DrawSliders();
128 void
129 TouchpadView::AttachedToWindow()
131 if (!fOffScreenView)
132 fOffScreenView = new BView(Bounds(), "", B_FOLLOW_ALL, B_WILL_DRAW);
134 if (!fOffScreenBitmap) {
135 fOffScreenBitmap = new BBitmap(Bounds(), B_CMAP8, true, false);
137 if (fOffScreenBitmap && fOffScreenView)
138 fOffScreenBitmap->AddChild(fOffScreenView);
143 void
144 TouchpadView::SetValues(float rightRange, float bottomRange)
146 fXScrollRange = fPadRect.Width() * (1 - rightRange);
147 fYScrollRange = fPadRect.Height() * (1 - bottomRange);
148 Invalidate();
152 void
153 TouchpadView::GetPreferredSize(float* width, float* height)
155 if (width != NULL)
156 *width = fPrefRect.Width();
157 if (height != NULL)
158 *height = fPrefRect.Height();
162 void
163 TouchpadView::MouseMoved(BPoint point, uint32 transit, const BMessage* message)
165 if (fXTracking) {
166 if (point.x > fPadRect.right)
167 fXScrollRange = fPadRect.Width();
168 else if (point.x < fPadRect.left)
169 fXScrollRange = 0;
170 else
171 fXScrollRange = point.x - fPadRect.left;
173 DrawSliders();
176 if (fYTracking) {
177 if (point.y > fPadRect.bottom)
178 fYScrollRange = fPadRect.Height();
179 else if (point.y < fPadRect.top)
180 fYScrollRange = 0;
181 else
182 fYScrollRange = point.y - fPadRect.top;
184 DrawSliders();
190 void
191 TouchpadView::DrawSliders()
193 BView* view = fOffScreenView != NULL ? fOffScreenView : this;
195 if (!LockLooper())
196 return;
198 if (fOffScreenBitmap->Lock()) {
199 view->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
200 view->FillRect(Bounds());
201 view->SetHighColor(100, 100, 100);
202 view->FillRoundRect(fPadRect, 4, 4);
204 int32 dragSize = 3; // half drag size
206 // scroll areas
207 view->SetHighColor(145, 100, 100);
208 BRect rightRect(fPadRect.left + fXScrollRange, fPadRect.top,
209 fPadRect.right, fPadRect.bottom);
210 view->FillRoundRect(rightRect, 4, 4);
212 BRect bottomRect(fPadRect.left, fPadRect.top + fYScrollRange,
213 fPadRect.right, fPadRect.bottom);
214 view->FillRoundRect(bottomRect, 4, 4);
216 // Stroke Rect
217 view->SetHighColor(100, 100, 100);
218 view->SetPenSize(2);
219 view->StrokeRoundRect(fPadRect, 4, 4);
221 // x scroll range line
222 view->SetHighColor(200, 0, 0);
223 view->StrokeLine(BPoint(fPadRect.left + fXScrollRange, fPadRect.top),
224 BPoint(fPadRect.left + fXScrollRange, fPadRect.bottom));
226 fXScrollDragZone = BRect(fPadRect.left + fXScrollRange - dragSize,
227 fPadRect.top - dragSize, fPadRect.left + fXScrollRange + dragSize,
228 fPadRect.bottom + dragSize);
229 fXScrollDragZone1 = BRect(fPadRect.left + fXScrollRange - dragSize,
230 fPadRect.top - dragSize, fPadRect.left + fXScrollRange + dragSize,
231 fPadRect.top + dragSize);
232 view->FillRect(fXScrollDragZone1);
233 fXScrollDragZone2 = BRect(fPadRect.left + fXScrollRange - dragSize,
234 fPadRect.bottom - dragSize,
235 fPadRect.left + fXScrollRange + dragSize,
236 fPadRect.bottom + dragSize);
237 view->FillRect(fXScrollDragZone2);
239 // y scroll range line
240 view->StrokeLine(BPoint(fPadRect.left, fPadRect.top + fYScrollRange),
241 BPoint(fPadRect.right, fPadRect.top + fYScrollRange));
243 fYScrollDragZone = BRect(fPadRect.left - dragSize,
244 fPadRect.top + fYScrollRange - dragSize,
245 fPadRect.right + dragSize,
246 fPadRect.top + fYScrollRange + dragSize);
247 fYScrollDragZone1 = BRect(fPadRect.left - dragSize,
248 fPadRect.top + fYScrollRange - dragSize, fPadRect.left + dragSize,
249 fPadRect.top + fYScrollRange + dragSize);
250 view->FillRect(fYScrollDragZone1);
251 fYScrollDragZone2 = BRect(fPadRect.right - dragSize,
252 fPadRect.top + fYScrollRange - dragSize, fPadRect.right + dragSize,
253 fPadRect.top + fYScrollRange + dragSize);
254 view->FillRect(fYScrollDragZone2);
256 view->Sync();
257 fOffScreenBitmap->Unlock();
258 DrawBitmap(fOffScreenBitmap, B_ORIGIN);
261 UnlockLooper();
265 // #pragma mark - TouchpadPrefView
268 TouchpadPrefView::TouchpadPrefView()
270 BGroupView()
272 SetupView();
273 // set view values
274 SetValues(&fTouchpadPref.Settings());
278 TouchpadPrefView::~TouchpadPrefView()
283 void
284 TouchpadPrefView::MessageReceived(BMessage* message)
286 touchpad_settings& settings = fTouchpadPref.Settings();
288 switch (message->what) {
289 case SCROLL_AREA_CHANGED:
290 settings.scroll_rightrange = fTouchpadView->GetRightScrollRatio();
291 settings.scroll_bottomrange = fTouchpadView->GetBottomScrollRatio();
292 fRevertButton->SetEnabled(true);
293 fTouchpadPref.UpdateSettings();
294 break;
296 case SCROLL_CONTROL_CHANGED:
297 settings.scroll_twofinger = fTwoFingerBox->Value() == B_CONTROL_ON;
298 settings.scroll_twofinger_horizontal
299 = fTwoFingerHorizontalBox->Value() == B_CONTROL_ON;
300 settings.scroll_acceleration = fScrollAccelSlider->Value();
301 settings.scroll_xstepsize = (20 - fScrollStepXSlider->Value()) * 3;
302 settings.scroll_ystepsize = (20 - fScrollStepYSlider->Value()) * 3;
303 fRevertButton->SetEnabled(true);
304 fTwoFingerHorizontalBox->SetEnabled(settings.scroll_twofinger);
305 fTouchpadPref.UpdateSettings();
306 break;
308 case TAP_CONTROL_CHANGED:
309 settings.tapgesture_sensibility = fTapSlider->Value();
310 fRevertButton->SetEnabled(true);
311 fTouchpadPref.UpdateSettings();
312 break;
314 case DEFAULT_SETTINGS:
315 fTouchpadPref.Defaults();
316 fRevertButton->SetEnabled(true);
317 fTouchpadPref.UpdateSettings();
318 SetValues(&settings);
319 break;
321 case REVERT_SETTINGS:
322 fTouchpadPref.Revert();
323 fTouchpadPref.UpdateSettings();
324 fRevertButton->SetEnabled(false);
325 SetValues(&settings);
326 break;
328 default:
329 BView::MessageReceived(message);
334 void
335 TouchpadPrefView::AttachedToWindow()
337 fTouchpadView->SetTarget(this);
338 fTwoFingerBox->SetTarget(this);
339 fTwoFingerHorizontalBox->SetTarget(this);
340 fScrollStepXSlider->SetTarget(this);
341 fScrollStepYSlider->SetTarget(this);
342 fScrollAccelSlider->SetTarget(this);
343 fTapSlider->SetTarget(this);
344 fDefaultButton->SetTarget(this);
345 fRevertButton->SetTarget(this);
346 BSize size = PreferredSize();
347 Window()->ResizeTo(size.width, size.height);
349 BPoint position = fTouchpadPref.WindowPosition();
350 // center window on screen if it had a bad position
351 if (position.x < 0 && position.y < 0)
352 Window()->CenterOnScreen();
353 else
354 Window()->MoveTo(position);
358 void
359 TouchpadPrefView::DetachedFromWindow()
361 fTouchpadPref.SetWindowPosition(Window()->Frame().LeftTop());
365 void
366 TouchpadPrefView::SetupView()
368 SetLayout(new BGroupLayout(B_VERTICAL));
369 BBox* scrollBox = new BBox("Touchpad");
370 scrollBox->SetLabel(B_TRANSLATE("Scrolling"));
372 fTouchpadView = new TouchpadView(BRect(0, 0, 130, 120));
373 fTouchpadView->SetExplicitMaxSize(BSize(130, 120));
375 // Create the "Mouse Speed" slider...
376 fScrollAccelSlider = new BSlider("scroll_accel",
377 B_TRANSLATE("Acceleration"),
378 new BMessage(SCROLL_CONTROL_CHANGED), 0, 20, B_HORIZONTAL);
379 fScrollAccelSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
380 fScrollAccelSlider->SetHashMarkCount(7);
381 fScrollAccelSlider->SetLimitLabels(B_TRANSLATE("Slow"),
382 B_TRANSLATE("Fast"));
383 fScrollAccelSlider->SetExplicitMinSize(BSize(150, B_SIZE_UNSET));
385 fScrollStepXSlider = new BSlider("scroll_stepX",
386 B_TRANSLATE("Horizontal"),
387 new BMessage(SCROLL_CONTROL_CHANGED),
388 0, 20, B_HORIZONTAL);
389 fScrollStepXSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
390 fScrollStepXSlider->SetHashMarkCount(7);
391 fScrollStepXSlider->SetLimitLabels(B_TRANSLATE("Slow"),
392 B_TRANSLATE("Fast"));
394 fScrollStepYSlider = new BSlider("scroll_stepY",
395 B_TRANSLATE("Vertical"),
396 new BMessage(SCROLL_CONTROL_CHANGED), 0, 20, B_HORIZONTAL);
397 fScrollStepYSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
398 fScrollStepYSlider->SetHashMarkCount(7);
399 fScrollStepYSlider->SetLimitLabels(B_TRANSLATE("Slow"),
400 B_TRANSLATE("Fast"));
402 fTwoFingerBox = new BCheckBox(B_TRANSLATE("Two finger scrolling"),
403 new BMessage(SCROLL_CONTROL_CHANGED));
404 fTwoFingerHorizontalBox = new BCheckBox(
405 B_TRANSLATE("Horizontal scrolling"),
406 new BMessage(SCROLL_CONTROL_CHANGED));
408 float spacing = be_control_look->DefaultItemSpacing();
410 BView* scrollPrefLeftLayout
411 = BLayoutBuilder::Group<>(B_VERTICAL, 0)
412 .Add(fTouchpadView)
413 .AddStrut(spacing)
414 .Add(fTwoFingerBox)
415 .AddGroup(B_HORIZONTAL, 0)
416 .AddStrut(spacing * 2)
417 .Add(fTwoFingerHorizontalBox)
418 .End()
419 .AddGlue()
420 .View();
422 BGroupView* scrollPrefRightLayout = new BGroupView(B_VERTICAL);
423 scrollPrefRightLayout->AddChild(fScrollAccelSlider);
424 scrollPrefRightLayout->AddChild(fScrollStepXSlider);
425 scrollPrefRightLayout->AddChild(fScrollStepYSlider);
427 BGroupLayout* scrollPrefLayout = new BGroupLayout(B_HORIZONTAL);
428 scrollPrefLayout->SetSpacing(spacing);
429 scrollPrefLayout->SetInsets(spacing,
430 scrollBox->TopBorderOffset() * 2 + spacing, spacing, spacing);
431 scrollBox->SetLayout(scrollPrefLayout);
433 scrollPrefLayout->AddView(scrollPrefLeftLayout);
434 scrollPrefLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(spacing
435 * 1.5));
436 scrollPrefLayout->AddView(scrollPrefRightLayout);
438 BBox* tapBox = new BBox("tapbox");
439 tapBox->SetLabel(B_TRANSLATE("Tapping"));
441 BGroupLayout* tapPrefLayout = new BGroupLayout(B_HORIZONTAL);
442 tapPrefLayout->SetInsets(spacing, tapBox->TopBorderOffset() * 2 + spacing,
443 spacing, spacing);
444 tapBox->SetLayout(tapPrefLayout);
446 fTapSlider = new BSlider("tap_sens", B_TRANSLATE("Sensitivity"),
447 new BMessage(TAP_CONTROL_CHANGED), 0, spacing * 2, B_HORIZONTAL);
448 fTapSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
449 fTapSlider->SetHashMarkCount(7);
450 fTapSlider->SetLimitLabels(B_TRANSLATE("Off"), B_TRANSLATE("High"));
452 tapPrefLayout->AddView(fTapSlider);
454 fDefaultButton = new BButton(B_TRANSLATE("Defaults"),
455 new BMessage(DEFAULT_SETTINGS));
457 fRevertButton = new BButton(B_TRANSLATE("Revert"),
458 new BMessage(REVERT_SETTINGS));
459 fRevertButton->SetEnabled(false);
461 BLayoutBuilder::Group<>(this, B_VERTICAL)
462 .SetInsets(B_USE_DEFAULT_SPACING)
463 .Add(scrollBox)
464 .Add(tapBox)
465 .AddGroup(B_HORIZONTAL)
466 .Add(fDefaultButton)
467 .Add(fRevertButton)
468 .AddGlue()
469 .End()
470 .End();
474 void
475 TouchpadPrefView::SetValues(touchpad_settings* settings)
477 fTouchpadView->SetValues(settings->scroll_rightrange,
478 settings->scroll_bottomrange);
479 fTwoFingerBox->SetValue(settings->scroll_twofinger
480 ? B_CONTROL_ON : B_CONTROL_OFF);
481 fTwoFingerHorizontalBox->SetValue(settings->scroll_twofinger_horizontal
482 ? B_CONTROL_ON : B_CONTROL_OFF);
483 fTwoFingerHorizontalBox->SetEnabled(settings->scroll_twofinger);
484 fScrollStepXSlider->SetValue(20 - settings->scroll_xstepsize / 2);
485 fScrollStepYSlider->SetValue(20 - settings->scroll_ystepsize / 2);
486 fScrollAccelSlider->SetValue(settings->scroll_acceleration);
487 fTapSlider->SetValue(settings->tapgesture_sensibility);