Completed Mouse and Touchppad preferences

Complete working and view of pointing devices(mouse and touchpad).

Resolve some issues.
Added the Jamfile

Change-Id: I4db021cb8c63971e5af60bd254c8b3b588d023e9
Reviewed-on: https://review.haiku-os.org/c/1426
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
Preetpal Kaur 2019-05-01 22:06:27 +05:30 committed by Kacper Kasper
parent 698c471f17
commit 5e9685caa8
19 changed files with 2695 additions and 0 deletions

View File

@ -6,6 +6,7 @@ SubInclude HAIKU_TOP src preferences bluetooth ;
SubInclude HAIKU_TOP src preferences datatranslations ;
SubInclude HAIKU_TOP src preferences deskbar ;
SubInclude HAIKU_TOP src preferences filetypes ;
SubInclude HAIKU_TOP src preferences input ;
SubInclude HAIKU_TOP src preferences joysticks ;
SubInclude HAIKU_TOP src preferences keyboard ;
SubInclude HAIKU_TOP src preferences keymap ;

View File

@ -0,0 +1,77 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#include "Input.h"
#include <GroupLayout.h>
#include <GroupLayoutBuilder.h>
#include "InputConstants.h"
#include "InputMouse.h"
#include "InputWindow.h"
#include "MouseSettings.h"
#include "MouseView.h"
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "InputApplication"
const char* kSignature = "application/x-vnd.Haiku-Input";
InputApplication::InputApplication()
:
BApplication(kSignature)
{
BRect rect(0, 0, 600, 500);
InputWindow* window = new InputWindow(rect);
window->Show();
}
void
InputApplication::MessageReceived(BMessage* message)
{
switch (message->what) {
case kMsgMouseType:
case kMsgMouseMap:
case kMsgMouseFocusMode:
case kMsgFollowsMouseMode:
case kMsgAcceptFirstClick:
case kMsgDoubleClickSpeed:
case kMsgMouseSpeed:
case kMsgAccelerationFactor:
case kMsgDefaults:
case kMsgRevert:
{
fWindow->PostMessage(message);
break;
}
case SCROLL_AREA_CHANGED:
case SCROLL_CONTROL_CHANGED:
case TAP_CONTROL_CHANGED:
case DEFAULT_SETTINGS:
case REVERT_SETTINGS:
{
fWindow->PostMessage(message);
break;
}
default:
BApplication::MessageReceived(message);
}
};
int
main(int /*argc*/, char** /*argv*/)
{
InputApplication app;
app.Run();
return 0;
}

View File

@ -0,0 +1,35 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#ifndef INPUT_H
#define INPUT_H
#include <Application.h>
#include <Catalog.h>
#include <Locale.h>
#include "MouseSettings.h"
#include "InputMouse.h"
#include "InputWindow.h"
class SettingsView;
class MouseSettings;
class InputApplication : public BApplication {
public:
InputApplication();
void MessageReceived(BMessage* message);
private:
InputWindow* fWindow;
};
#endif /* INPUT_H */

View File

@ -0,0 +1,35 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#ifndef INPUT_MOUSE_CONSTANTS_H
#define INPUT_MOUSE_CONSTANTS_H
#include <SupportDefs.h>
const uint32 kMsgDefaults = 'BTde';
const uint32 kMsgRevert = 'BTre';
const uint32 kMsgUpdate = 'BTup';
const uint32 kMsgDoubleClickSpeed = 'SLdc';
const uint32 kMsgCursorSpeed = 'SLcs';
const uint32 kMsgFollowsMouseMode = 'PUff';
const uint32 kMsgMouseFocusMode = 'PUmf';
const uint32 kMsgAcceptFirstClick = 'PUaf';
const uint32 kMsgMouseType = 'PUmt';
const uint32 kMsgMouseMap = 'PUmm';
const uint32 kMsgMouseSpeed = 'SLms';
const uint32 kMsgAccelerationFactor = 'SLma';
const uint32 kMsgSelected = 'SMms';
const uint32 kMsgAddToDeviceList = 'SAdl';
const uint32 kMsgPointingDevices = 'MTss';
const uint32 kBorderSpace = 10;
const uint32 kItemSpace = 7;
#endif /* INPUT_MOUSE_CONSTANTS_H */

View File

@ -0,0 +1,217 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#include "InputMouse.h"
#include <Application.h>
#include <Bitmap.h>
#include <Box.h>
#include <Button.h>
#include <Catalog.h>
#include <ControlLook.h>
#include <Debug.h>
#include <CheckBox.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <PopUpMenu.h>
#include <LayoutBuilder.h>
#include <Locale.h>
#include <Slider.h>
#include <Screen.h>
#include <StringView.h>
#include <TabView.h>
#include "InputConstants.h"
#include "InputWindow.h"
#include "MouseSettings.h"
#include "MouseView.h"
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "InputMouse"
static const bigtime_t kDefaultClickSpeed = 500000;
static const int32 kDefaultMouseSpeed = 65536;
static const int32 kDefaultMouseType = 3; // 3 button mouse
static const int32 kDefaultAccelerationFactor = 65536;
static const bool kDefaultAcceptFirstClick = false;
InputMouse::InputMouse()
: BView("InputMouse", B_WILL_DRAW)
{
fSettingsView = new SettingsView(fSettings);
fDefaultsButton = new BButton(B_TRANSLATE("Defaults"),
new BMessage(kMsgDefaults));
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton = new BButton(B_TRANSLATE("Revert"),
new BMessage(kMsgRevert));
fRevertButton->SetEnabled(false);
BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
.Add(fSettingsView)
.Add(new BSeparatorView(B_HORIZONTAL))
.AddGroup(B_HORIZONTAL)
.Add(fDefaultsButton)
.Add(fRevertButton)
.AddGlue()
.End()
.End();
}
InputMouse::~InputMouse()
{
}
void
InputMouse::MessageReceived(BMessage* message)
{
switch (message->what) {
case kMsgDefaults: {
fSettings.Defaults();
fSettingsView->UpdateFromSettings();
fDefaultsButton->SetEnabled(false);
fRevertButton->SetEnabled(fSettings.IsRevertable());
break;
}
case kMsgRevert: {
fSettings.Revert();
fSettingsView->UpdateFromSettings();
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(false);
break;
}
case kMsgMouseType:
{
int32 type;
if (message->FindInt32("index", &type) == B_OK) {
fSettings.SetMouseType(++type);
fSettingsView->SetMouseType(type);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
}
break;
}
case kMsgMouseFocusMode:
{
int32 mode;
if (message->FindInt32("mode", &mode) == B_OK) {
fSettings.SetMouseMode((mode_mouse)mode);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
fSettingsView->fFocusFollowsMouseMenu->SetEnabled(
mode == B_FOCUS_FOLLOWS_MOUSE);
fSettingsView->fAcceptFirstClickBox->SetEnabled(
mode != B_FOCUS_FOLLOWS_MOUSE);
}
break;
}
case kMsgFollowsMouseMode:
{
int32 mode;
if (message->FindInt32("mode_focus_follows_mouse", &mode)
== B_OK) {
fSettings.SetFocusFollowsMouseMode(
(mode_focus_follows_mouse)mode);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
}
break;
}
case kMsgAcceptFirstClick:
{
BHandler *handler;
if (message->FindPointer("source",
reinterpret_cast<void**>(&handler)) == B_OK) {
bool acceptFirstClick = false;
BCheckBox *acceptFirstClickBox =
dynamic_cast<BCheckBox*>(handler);
if (acceptFirstClickBox)
acceptFirstClick = acceptFirstClickBox->Value()
== B_CONTROL_ON;
fSettings.SetAcceptFirstClick(acceptFirstClick);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
}
break;
}
case kMsgDoubleClickSpeed:
{
int32 value;
if (message->FindInt32("be:value", &value) == B_OK) {
// slow = 1000000, fast = 0
fSettings.SetClickSpeed(value * 1000);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
}
break;
}
case kMsgMouseSpeed:
{
int32 value;
if (message->FindInt32("be:value", &value) == B_OK) {
// slow = 8192, fast = 524287
fSettings.SetMouseSpeed((int32)pow(2,
value * 6.0 / 1000) * 8192);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
}
break;
}
case kMsgAccelerationFactor:
{
int32 value;
if (message->FindInt32("be:value", &value) == B_OK) {
// slow = 0, fast = 262144
fSettings.SetAccelerationFactor((int32)pow(
value * 4.0 / 1000, 2) * 16384);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
}
break;
}
case kMsgMouseMap:
{
int32 index;
int32 button;
if (message->FindInt32("index", &index) == B_OK
&& message->FindInt32("button", &button) == B_OK) {
int32 mapping = B_PRIMARY_MOUSE_BUTTON;
switch (index) {
case 1:
mapping = B_SECONDARY_MOUSE_BUTTON;
break;
case 2:
mapping = B_TERTIARY_MOUSE_BUTTON;
break;
}
fSettings.SetMapping(button, mapping);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
fSettingsView->MouseMapUpdated();
}
break;
}
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#ifndef INPUT_MOUSE_H
#define INPUT_MOUSE_H
#include <Box.h>
#include <Bitmap.h>
#include <Button.h>
#include <CheckBox.h>
#include <Slider.h>
#include <PopUpMenu.h>
#include <MenuField.h>
#include <ListView.h>
#include <TabView.h>
#include <View.h>
#include "InputWindow.h"
#include "MouseSettings.h"
#include "MouseView.h"
#include "SettingsView.h"
#define MOUSE_SETTINGS 'Mss'
class BTabView;
class InputMouse : public BView {
public:
InputMouse();
virtual ~InputMouse();
void SetMouseType(int32 type);
void MessageReceived(BMessage* message);
private:
typedef BBox inherited;
SettingsView* fSettingsView;
MouseView* fMouseView;
BButton* fDefaultsButton;
BButton* fRevertButton;
MouseSettings fSettings;
mouse_settings fMouseSettings, fOriginalSettings;
};
#endif /* INPUT_MOUSE_H */

View File

@ -0,0 +1,186 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#include "InputTouchpadPref.h"
#include <List.h>
#include <FindDirectory.h>
#include <File.h>
#include <String.h>
#include <keyboard_mouse_driver.h>
TouchpadPref::TouchpadPref()
{
fConnected = false;
// default center position
fWindowPosition.x = -1;
fWindowPosition.y = -1;
ConnectToTouchPad();
if (LoadSettings() != B_OK)
Defaults();
fStartSettings = fSettings;
}
TouchpadPref::~TouchpadPref()
{
if (fConnected)
delete fTouchPad;
SaveSettings();
}
void
TouchpadPref::Revert()
{
fSettings = fStartSettings;
}
status_t
TouchpadPref::UpdateSettings()
{
if (!fConnected)
return B_ERROR;
LOG("UpdateSettings of device %s\n", fTouchPad->Name());
BMessage msg;
msg.AddBool("scroll_twofinger", fSettings.scroll_twofinger);
msg.AddBool("scroll_twofinger_horizontal",
fSettings.scroll_twofinger_horizontal);
msg.AddFloat("scroll_rightrange", fSettings.scroll_rightrange);
msg.AddFloat("scroll_bottomrange", fSettings.scroll_bottomrange);
msg.AddInt16("scroll_xstepsize", fSettings.scroll_xstepsize);
msg.AddInt16("scroll_ystepsize", fSettings.scroll_ystepsize);
msg.AddInt8("scroll_acceleration", fSettings.scroll_acceleration);
msg.AddInt8("tapgesture_sensibility", fSettings.tapgesture_sensibility);
return fTouchPad->Control(MS_SET_TOUCHPAD_SETTINGS, &msg);
}
void
TouchpadPref::Defaults()
{
fSettings = kDefaultTouchpadSettings;
}
status_t
TouchpadPref::GetSettingsPath(BPath &path)
{
status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
if (status < B_OK)
return status;
return path.Append(TOUCHPAD_SETTINGS_FILE);
}
status_t
TouchpadPref::LoadSettings()
{
BPath path;
status_t status = GetSettingsPath(path);
if (status != B_OK)
return status;
BFile settingsFile(path.Path(), B_READ_ONLY);
status = settingsFile.InitCheck();
if (status != B_OK)
return status;
if (settingsFile.Read(&fSettings, sizeof(touchpad_settings))
!= sizeof(touchpad_settings)) {
LOG("failed to load settings\n");
return B_ERROR;
}
if (settingsFile.Read(&fWindowPosition, sizeof(BPoint))
!= sizeof(BPoint)) {
LOG("failed to load settings\n");
return B_ERROR;
}
return B_OK;
}
status_t
TouchpadPref::SaveSettings()
{
BPath path;
status_t status = GetSettingsPath(path);
if (status != B_OK)
return status;
BFile settingsFile(path.Path(), B_READ_WRITE | B_CREATE_FILE);
status = settingsFile.InitCheck();
if (status != B_OK)
return status;
if (settingsFile.Write(&fSettings, sizeof(touchpad_settings))
!= sizeof(touchpad_settings)) {
LOG("can't save settings\n");
return B_ERROR;
}
if (settingsFile.Write(&fWindowPosition, sizeof(BPoint))
!= sizeof(BPoint)) {
LOG("can't save window position\n");
return B_ERROR;
}
return B_OK;
}
status_t
TouchpadPref::ConnectToTouchPad()
{
BList devList;
status_t status = get_input_devices(&devList);
if (status != B_OK)
return status;
int32 i = 0;
while (true) {
BInputDevice* dev = (BInputDevice*)devList.ItemAt(i);
if (dev == NULL)
break;
i++;
LOG("input device %s\n", dev->Name());
BString name = dev->Name();
if (name.FindFirst("Touchpad") >= 0
&& dev->Type() == B_POINTING_DEVICE
&& !fConnected) {
fConnected = true;
fTouchPad = dev;
// Don't bail out here, since we need to delete the other devices
// yet.
} else {
delete dev;
}
}
if (fConnected)
return B_OK;
LOG("touchpad input device NOT found\n");
return B_ENTRY_NOT_FOUND;
}

View File

@ -0,0 +1,62 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#ifndef TOUCHPAD_PREF_H
#define TOUCHPAD_PREF_H
#include <Debug.h>
#include "touchpad_settings.h"
#include <Input.h>
#include <Path.h>
#if DEBUG
# define LOG(text...) PRINT((text))
#else
# define LOG(text...)
#endif
class TouchpadPref {
public:
TouchpadPref();
~TouchpadPref();
void Revert();
void Defaults();
BPoint WindowPosition()
{ return fWindowPosition; }
void SetWindowPosition(BPoint position)
{ fWindowPosition = position; }
touchpad_settings& Settings()
{ return fSettings; }
bool IsTouchpadConnected()
{ return fConnected; }
status_t UpdateSettings();
private:
status_t GetSettingsPath(BPath& path);
status_t LoadSettings();
status_t SaveSettings();
status_t ConnectToTouchPad();
bool fConnected;
BInputDevice* fTouchPad;
touchpad_settings fSettings;
touchpad_settings fStartSettings;
BPoint fWindowPosition;
};
#endif // TOUCHPAD_PREF_H

View File

@ -0,0 +1,507 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#include "InputTouchpadPrefView.h"
#include <stdio.h>
#include <Alert.h>
#include <Box.h>
#include <Catalog.h>
#include <CheckBox.h>
#include <ControlLook.h>
#include <File.h>
#include <FindDirectory.h>
#include <Input.h>
#include <LayoutBuilder.h>
#include <Locale.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <Message.h>
#include <Path.h>
#include <Screen.h>
#include <SeparatorView.h>
#include <SpaceLayoutItem.h>
#include <Window.h>
#include <keyboard_mouse_driver.h>
const uint32 SCROLL_X_DRAG = 'sxdr';
const uint32 SCROLL_Y_DRAG = 'sydr';
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "TouchpadPrefView"
TouchpadView::TouchpadView(BRect frame)
:
BView(frame, "TouchpadView", B_FOLLOW_NONE, B_WILL_DRAW)
{
fXTracking = false;
fYTracking = false;
fOffScreenView = NULL;
fOffScreenBitmap = NULL;
fPrefRect = frame;
fPadRect = fPrefRect;
fPadRect.InsetBy(10, 10);
fXScrollRange = fPadRect.Width();
fYScrollRange = fPadRect.Height();
}
TouchpadView::~TouchpadView()
{
delete fOffScreenBitmap;
}
void
TouchpadView::Draw(BRect updateRect)
{
DrawSliders();
}
void
TouchpadView::MouseDown(BPoint point)
{
if (fXScrollDragZone.Contains(point)) {
fXTracking = true;
fOldXScrollRange = fXScrollRange;
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
}
if (fYScrollDragZone.Contains(point)) {
fYTracking = true;
fOldYScrollRange = fYScrollRange;
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
}
}
void
TouchpadView::MouseUp(BPoint point)
{
if (!fXTracking && !fYTracking)
return;
fXTracking = false;
fYTracking = false;
const float kSoftScrollLimit = 0.7;
int32 result = 0;
if (GetRightScrollRatio() > kSoftScrollLimit
|| GetBottomScrollRatio() > kSoftScrollLimit) {
BAlert* alert = new BAlert(B_TRANSLATE("Please confirm"),
B_TRANSLATE("The new scroll area is very large and may impede "
"normal mouse operation. Do you really want to change it?"),
B_TRANSLATE("OK"), B_TRANSLATE("Cancel"),
NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
alert->SetShortcut(1, B_ESCAPE);
result = alert->Go();
}
if (result == 0) {
BMessage msg(SCROLL_AREA_CHANGED);
Invoke(&msg);
} else {
if (GetRightScrollRatio() > kSoftScrollLimit)
fXScrollRange = fOldXScrollRange;
if (GetBottomScrollRatio() > kSoftScrollLimit)
fYScrollRange = fOldYScrollRange;
DrawSliders();
}
}
void
TouchpadView::AttachedToWindow()
{
if (!fOffScreenView)
fOffScreenView = new BView(Bounds(), "", B_FOLLOW_ALL, B_WILL_DRAW);
if (!fOffScreenBitmap) {
fOffScreenBitmap = new BBitmap(Bounds(), B_CMAP8, true, false);
if (fOffScreenBitmap && fOffScreenView)
fOffScreenBitmap->AddChild(fOffScreenView);
}
}
void
TouchpadView::SetValues(float rightRange, float bottomRange)
{
fXScrollRange = fPadRect.Width() * (1 - rightRange);
fYScrollRange = fPadRect.Height() * (1 - bottomRange);
Invalidate();
}
void
TouchpadView::GetPreferredSize(float* width, float* height)
{
if (width != NULL)
*width = fPrefRect.Width();
if (height != NULL)
*height = fPrefRect.Height();
}
void
TouchpadView::MouseMoved(BPoint point, uint32 transit, const BMessage* message)
{
if (fXTracking) {
if (point.x > fPadRect.right)
fXScrollRange = fPadRect.Width();
else if (point.x < fPadRect.left)
fXScrollRange = 0;
else
fXScrollRange = point.x - fPadRect.left;
DrawSliders();
}
if (fYTracking) {
if (point.y > fPadRect.bottom)
fYScrollRange = fPadRect.Height();
else if (point.y < fPadRect.top)
fYScrollRange = 0;
else
fYScrollRange = point.y - fPadRect.top;
DrawSliders();
}
}
void
TouchpadView::DrawSliders()
{
BView* view = fOffScreenView != NULL ? fOffScreenView : this;
if (!LockLooper())
return;
if (fOffScreenBitmap->Lock()) {
view->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
view->FillRect(Bounds());
view->SetHighColor(100, 100, 100);
view->FillRoundRect(fPadRect, 4, 4);
int32 dragSize = 3; // half drag size
// scroll areas
view->SetHighColor(145, 100, 100);
BRect rightRect(fPadRect.left + fXScrollRange, fPadRect.top,
fPadRect.right, fPadRect.bottom);
view->FillRoundRect(rightRect, 4, 4);
BRect bottomRect(fPadRect.left, fPadRect.top + fYScrollRange,
fPadRect.right, fPadRect.bottom);
view->FillRoundRect(bottomRect, 4, 4);
// Stroke Rect
view->SetHighColor(100, 100, 100);
view->SetPenSize(2);
view->StrokeRoundRect(fPadRect, 4, 4);
// x scroll range line
view->SetHighColor(200, 0, 0);
view->StrokeLine(BPoint(fPadRect.left + fXScrollRange, fPadRect.top),
BPoint(fPadRect.left + fXScrollRange, fPadRect.bottom));
fXScrollDragZone = BRect(fPadRect.left + fXScrollRange - dragSize,
fPadRect.top - dragSize, fPadRect.left + fXScrollRange + dragSize,
fPadRect.bottom + dragSize);
BRect xscrollDragZone1 = BRect(fPadRect.left + fXScrollRange - dragSize,
fPadRect.top - dragSize, fPadRect.left + fXScrollRange + dragSize,
fPadRect.top + dragSize);
view->FillRect(xscrollDragZone1);
BRect xscrollDragZone2 = BRect(fPadRect.left + fXScrollRange - dragSize,
fPadRect.bottom - dragSize,
fPadRect.left + fXScrollRange + dragSize,
fPadRect.bottom + dragSize);
view->FillRect(xscrollDragZone2);
// y scroll range line
view->StrokeLine(BPoint(fPadRect.left, fPadRect.top + fYScrollRange),
BPoint(fPadRect.right, fPadRect.top + fYScrollRange));
fYScrollDragZone = BRect(fPadRect.left - dragSize,
fPadRect.top + fYScrollRange - dragSize,
fPadRect.right + dragSize,
fPadRect.top + fYScrollRange + dragSize);
BRect yscrollDragZone1 = BRect(fPadRect.left - dragSize,
fPadRect.top + fYScrollRange - dragSize, fPadRect.left + dragSize,
fPadRect.top + fYScrollRange + dragSize);
view->FillRect(yscrollDragZone1);
BRect yscrollDragZone2 = BRect(fPadRect.right - dragSize,
fPadRect.top + fYScrollRange - dragSize, fPadRect.right + dragSize,
fPadRect.top + fYScrollRange + dragSize);
view->FillRect(yscrollDragZone2);
view->Sync();
fOffScreenBitmap->Unlock();
DrawBitmap(fOffScreenBitmap, B_ORIGIN);
}
UnlockLooper();
}
// #pragma mark - TouchpadPrefView
TouchpadPrefView::TouchpadPrefView(const char* name)
:
BGroupView(name)
{
SetupView();
// set view values
SetValues(&fTouchpadPref.Settings());
if (fTouchpadPref.IsTouchpadConnected() == false) {
DisablePref();
fShowWarning->SetText(B_TRANSLATE("No touchpad found, the settings "
"will have no effect."));
}
else
fShowWarning->Hide();
}
TouchpadPrefView::~TouchpadPrefView()
{
}
void
TouchpadPrefView::MessageReceived(BMessage* message)
{
touchpad_settings& settings = fTouchpadPref.Settings();
switch (message->what) {
case SCROLL_AREA_CHANGED:
settings.scroll_rightrange = fTouchpadView->GetRightScrollRatio();
settings.scroll_bottomrange = fTouchpadView->GetBottomScrollRatio();
fTouchpadPref.UpdateSettings();
break;
case SCROLL_CONTROL_CHANGED:
settings.scroll_twofinger = fTwoFingerBox->Value() == B_CONTROL_ON;
settings.scroll_twofinger_horizontal
= fTwoFingerHorizontalBox->Value() == B_CONTROL_ON;
settings.scroll_acceleration = fScrollAccelSlider->Value();
settings.scroll_xstepsize = (20 - fScrollStepXSlider->Value()) * 3;
settings.scroll_ystepsize = (20 - fScrollStepYSlider->Value()) * 3;
fTwoFingerHorizontalBox->SetEnabled(settings.scroll_twofinger);
fTouchpadPref.UpdateSettings();
break;
case TAP_CONTROL_CHANGED:
settings.tapgesture_sensibility = fTapSlider->Value();
fTouchpadPref.UpdateSettings();
break;
case DEFAULT_SETTINGS:
fTouchpadPref.Defaults();
fRevertButton->SetEnabled(true);
fTouchpadPref.UpdateSettings();
SetValues(&settings);
break;
case REVERT_SETTINGS:
fTouchpadPref.Revert();
fTouchpadPref.UpdateSettings();
fRevertButton->SetEnabled(false);
SetValues(&settings);
break;
default:
BView::MessageReceived(message);
}
}
void
TouchpadPrefView::AttachedToWindow()
{
fTouchpadView->SetTarget(this);
fTwoFingerBox->SetTarget(this);
fTwoFingerHorizontalBox->SetTarget(this);
fScrollStepXSlider->SetTarget(this);
fScrollStepYSlider->SetTarget(this);
fScrollAccelSlider->SetTarget(this);
fTapSlider->SetTarget(this);
fDefaultButton->SetTarget(this);
fRevertButton->SetTarget(this);
BSize size = PreferredSize();
Window()->ResizeTo(size.width, size.height);
BPoint position = fTouchpadPref.WindowPosition();
// center window on screen if it had a bad position
if (position.x < 0 && position.y < 0)
Window()->CenterOnScreen();
else
Window()->MoveTo(position);
}
void
TouchpadPrefView::DetachedFromWindow()
{
fTouchpadPref.SetWindowPosition(Window()->Frame().LeftTop());
}
void
TouchpadPrefView::SetupView()
{
SetLayout(new BGroupLayout(B_VERTICAL));
BBox* scrollBox = new BBox("Touchpad");
scrollBox->SetLabel(B_TRANSLATE("Scrolling"));
fTouchpadView = new TouchpadView(BRect(0, 0, 130, 120));
fTouchpadView->SetExplicitMaxSize(BSize(130, 120));
// Create the "Mouse Speed" slider...
fScrollAccelSlider = new BSlider("scroll_accel",
B_TRANSLATE("Acceleration"),
new BMessage(SCROLL_CONTROL_CHANGED), 0, 20, B_HORIZONTAL);
fScrollAccelSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
fScrollAccelSlider->SetHashMarkCount(7);
fScrollAccelSlider->SetLimitLabels(B_TRANSLATE("Slow"),
B_TRANSLATE("Fast"));
fScrollAccelSlider->SetExplicitMinSize(BSize(150, B_SIZE_UNSET));
fScrollStepXSlider = new BSlider("scroll_stepX",
B_TRANSLATE("Horizontal"),
new BMessage(SCROLL_CONTROL_CHANGED),
0, 20, B_HORIZONTAL);
fScrollStepXSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
fScrollStepXSlider->SetHashMarkCount(7);
fScrollStepXSlider->SetLimitLabels(B_TRANSLATE("Slow"),
B_TRANSLATE("Fast"));
fScrollStepYSlider = new BSlider("scroll_stepY",
B_TRANSLATE("Vertical"),
new BMessage(SCROLL_CONTROL_CHANGED), 0, 20, B_HORIZONTAL);
fScrollStepYSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
fScrollStepYSlider->SetHashMarkCount(7);
fScrollStepYSlider->SetLimitLabels(B_TRANSLATE("Slow"),
B_TRANSLATE("Fast"));
fTwoFingerBox = new BCheckBox(B_TRANSLATE("Two finger scrolling"),
new BMessage(SCROLL_CONTROL_CHANGED));
fTwoFingerHorizontalBox = new BCheckBox(
B_TRANSLATE("Horizontal scrolling"),
new BMessage(SCROLL_CONTROL_CHANGED));
float spacing = be_control_look->DefaultItemSpacing();
BView* scrollPrefLeftLayout
= BLayoutBuilder::Group<>(B_VERTICAL, 0)
.Add(fTouchpadView)
.AddStrut(spacing)
.Add(fTwoFingerBox)
.AddGroup(B_HORIZONTAL, 0)
.AddStrut(spacing * 2)
.Add(fTwoFingerHorizontalBox)
.End()
.AddGlue()
.View();
BGroupView* scrollPrefRightLayout = new BGroupView(B_VERTICAL);
scrollPrefRightLayout->AddChild(fScrollAccelSlider);
scrollPrefRightLayout->AddChild(fScrollStepXSlider);
scrollPrefRightLayout->AddChild(fScrollStepYSlider);
BGroupLayout* scrollPrefLayout = new BGroupLayout(B_HORIZONTAL);
scrollPrefLayout->SetSpacing(spacing);
scrollPrefLayout->SetInsets(spacing,
scrollBox->TopBorderOffset() * 2 + spacing, spacing, spacing);
scrollBox->SetLayout(scrollPrefLayout);
scrollPrefLayout->AddView(scrollPrefLeftLayout);
scrollPrefLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(spacing
* 1.5));
scrollPrefLayout->AddView(scrollPrefRightLayout);
BBox* tapBox = new BBox("tapbox");
tapBox->SetLabel(B_TRANSLATE("Tapping"));
BGroupLayout* tapPrefLayout = new BGroupLayout(B_HORIZONTAL);
tapPrefLayout->SetInsets(spacing, tapBox->TopBorderOffset() * 2 + spacing,
spacing, spacing);
tapBox->SetLayout(tapPrefLayout);
fTapSlider = new BSlider("tap_sens", B_TRANSLATE("Sensitivity"),
new BMessage(TAP_CONTROL_CHANGED), 0, spacing * 2, B_HORIZONTAL);
fTapSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
fTapSlider->SetHashMarkCount(7);
fTapSlider->SetLimitLabels(B_TRANSLATE("Off"), B_TRANSLATE("High"));
tapPrefLayout->AddView(fTapSlider);
fDefaultButton = new BButton(B_TRANSLATE("Defaults"),
new BMessage(DEFAULT_SETTINGS));
fRevertButton = new BButton(B_TRANSLATE("Revert"),
new BMessage(REVERT_SETTINGS));
fRevertButton->SetEnabled(false);
fShowWarning = new BStringView("warning", "");
BLayoutBuilder::Group<>(this, B_VERTICAL)
.SetInsets(B_USE_WINDOW_SPACING)
.Add(fShowWarning)
.Add(scrollBox)
.Add(tapBox)
.Add(new BSeparatorView(B_HORIZONTAL))
.AddGroup(B_HORIZONTAL)
.Add(fDefaultButton)
.Add(fRevertButton)
.AddGlue()
.End()
.End();
}
void
TouchpadPrefView::SetValues(touchpad_settings* settings)
{
fTouchpadView->SetValues(settings->scroll_rightrange,
settings->scroll_bottomrange);
fTwoFingerBox->SetValue(settings->scroll_twofinger
? B_CONTROL_ON : B_CONTROL_OFF);
fTwoFingerHorizontalBox->SetValue(settings->scroll_twofinger_horizontal
? B_CONTROL_ON : B_CONTROL_OFF);
fTwoFingerHorizontalBox->SetEnabled(settings->scroll_twofinger);
fScrollStepXSlider->SetValue(20 - settings->scroll_xstepsize / 2);
fScrollStepYSlider->SetValue(20 - settings->scroll_ystepsize / 2);
fScrollAccelSlider->SetValue(settings->scroll_acceleration);
fTapSlider->SetValue(settings->tapgesture_sensibility);
}
void
TouchpadPrefView::DisablePref()
{
fTwoFingerBox->SetEnabled(false);
fTwoFingerHorizontalBox->SetEnabled(false);
fTapSlider->SetEnabled(false);
fScrollAccelSlider->SetEnabled(false);
fScrollStepXSlider->SetEnabled(false);
fScrollStepYSlider->SetEnabled(false);
}

View File

@ -0,0 +1,106 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#ifndef TOUCHPAD_PREF_VIEW_H
#define TOUCHPAD_PREF_VIEW_H
#include <Bitmap.h>
#include <Button.h>
#include <CheckBox.h>
#include <GroupView.h>
#include <Invoker.h>
#include <StringView.h>
#include <Slider.h>
#include <View.h>
#include "InputTouchpadPref.h"
#include "touchpad_settings.h"
#include <Debug.h>
#if DEBUG
# define LOG(text...) PRINT((text))
#else
# define LOG(text...)
#endif
const uint SCROLL_AREA_CHANGED = '&sac';
const uint SCROLL_CONTROL_CHANGED = '&scc';
const uint TAP_CONTROL_CHANGED = '&tcc';
const uint DEFAULT_SETTINGS = '&dse';
const uint REVERT_SETTINGS = '&rse';
//! Shows a touchpad
class TouchpadView : public BView, public BInvoker {
public:
TouchpadView(BRect frame);
virtual ~TouchpadView();
virtual void Draw(BRect updateRect);
virtual void MouseDown(BPoint point);
virtual void MouseUp(BPoint point);
virtual void MouseMoved(BPoint point, uint32 transit,
const BMessage* dragMessage);
virtual void AttachedToWindow();
virtual void GetPreferredSize(float* width, float* height);
void SetValues(float rightRange, float bottomRange);
float GetRightScrollRatio()
{ return 1 - fXScrollRange / fPadRect.Width(); }
float GetBottomScrollRatio()
{ return 1
- fYScrollRange / fPadRect.Height(); }
private:
virtual void DrawSliders();
BRect fPrefRect;
BRect fPadRect;
BRect fXScrollDragZone;
float fXScrollRange;
float fOldXScrollRange;
BRect fYScrollDragZone;
float fYScrollRange;
float fOldYScrollRange;
bool fXTracking;
bool fYTracking;
BView* fOffScreenView;
BBitmap* fOffScreenBitmap;
};
class TouchpadPrefView : public BGroupView {
public:
TouchpadPrefView(const char* name);
virtual ~TouchpadPrefView();
virtual void MessageReceived(BMessage* message);
virtual void AttachedToWindow();
virtual void DetachedFromWindow();
void SetupView();
void SetValues(touchpad_settings *settings);
TouchpadPref fTouchpadPref;
private:
void DisablePref();
TouchpadView* fTouchpadView;
BCheckBox* fTwoFingerBox;
BCheckBox* fTwoFingerHorizontalBox;
BSlider* fScrollStepXSlider;
BSlider* fScrollStepYSlider;
BSlider* fScrollAccelSlider;
BSlider* fTapSlider;
BButton* fDefaultButton;
BButton* fRevertButton;
BStringView* fShowWarning;
};
#endif // TOUCHPAD_PREF_VIEW_H

View File

@ -0,0 +1,97 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#include <Alert.h>
#include <Alignment.h>
#include <Application.h>
#include <Button.h>
#include <CardLayout.h>
#include <CardView.h>
#include <Catalog.h>
#include <Control.h>
#include <ControlLook.h>
#include <LayoutBuilder.h>
#include <SplitView.h>
#include <Screen.h>
#include <TabView.h>
#include <stdio.h>
#include "InputWindow.h"
#include "InputDeviceView.h"
#include "MouseSettings.h"
#include "InputMouse.h"
#include "InputConstants.h"
#include "SettingsView.h"
#include "InputTouchpadPref.h"
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "InputWindow"
InputWindow::InputWindow(BRect _rect)
:
BWindow(_rect, B_TRANSLATE_SYSTEM_NAME("Input"), B_TITLED_WINDOW,
B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS
| B_AUTO_UPDATE_SIZE_LIMITS | B_QUIT_ON_WINDOW_CLOSE)
{
fInputMouse = new InputMouse();
fTouchpadPrefView = new TouchpadPrefView(B_TRANSLATE("Touchpad"));
fDeviceListView = new DeviceListView(B_TRANSLATE("Device List"));
fCardView = new BCardView();
fCardView->AddChild(fInputMouse);
fCardView->AddChild(fTouchpadPrefView);
BLayoutBuilder::Group<>(this, B_HORIZONTAL, 10)
.Add(fDeviceListView)
.AddGroup(B_VERTICAL,0)
.Add(fCardView)
.End();
}
void
InputWindow::MessageReceived(BMessage* message)
{
int32 name = message->GetInt32("index", 0);
switch (message->what) {
case ITEM_SELECTED:
{
fCardView->CardLayout()->SetVisibleItem(name);
}
case kMsgMouseType:
case kMsgMouseMap:
case kMsgMouseFocusMode:
case kMsgFollowsMouseMode:
case kMsgAcceptFirstClick:
case kMsgDoubleClickSpeed:
case kMsgMouseSpeed:
case kMsgAccelerationFactor:
case kMsgDefaults:
case kMsgRevert:
{
PostMessage(message, fInputMouse);
break;
}
case SCROLL_AREA_CHANGED:
case SCROLL_CONTROL_CHANGED:
case TAP_CONTROL_CHANGED:
case DEFAULT_SETTINGS:
case REVERT_SETTINGS:
{
PostMessage(message, fTouchpadPrefView);
break;
}
default:
BWindow::MessageReceived(message);
break;
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#ifndef INPUT_WINDOW_H
#define INPUT_WINDOW_H
#include <Window.h>
#include <View.h>
#include <ListItem.h>
#include <ListView.h>
#include <ScrollBar.h>
#include <ScrollView.h>
#include <SeparatorView.h>
#include <Box.h>
#include <CardView.h>
#include <Message.h>
#include "MouseSettings.h"
#include "InputMouse.h"
#include "InputTouchpadPrefView.h"
#include "touchpad_settings.h"
class BSplitView;
class BCardView;
class BCardLayout;
class DeviceListView;
class SettingsView;
class DeviceName;
class TouchpadPrefView;
class TouchpadPref;
class TouchpadView;
class InputDevices;
class InputMouse;
class InputWindow : public BWindow
{
public:
InputWindow(BRect rect);
void MessageReceived(BMessage* message);
private:
DeviceListView* fDeviceListView;
BCardView* fCardView;
MouseSettings fSettings;
SettingsView* fSettingsView;
InputMouse* fInputMouse;
TouchpadPrefView* fTouchpadPrefView;
TouchpadPref* fTouchpadPref;
};
#endif /* INPUT_WINDOW_H */

View File

@ -0,0 +1,29 @@
SubDir HAIKU_TOP src preferences input ;
UsePrivateHeaders input ;
Preference Input :
Input.cpp
InputWindow.cpp
InputDeviceView.cpp
InputTouchpadPref.cpp
InputTouchpadPrefView.cpp
InputMouse.cpp
MouseView.cpp
MouseSettings.cpp
SettingsView.cpp
: be [ TargetLibsupc++ ] localestub
;
DoCatalogs Input :
x-vnd.Haiku-Input
:
Input.cpp
InputWindow.cpp
InputDeviceView.cpp
InputTouchpadPref.cpp
InputTouchpadPrefView.cpp
InputMouse.cpp
MouseView.cpp
MouseSettings.cpp
SettingsView.cpp
;

View File

@ -0,0 +1,370 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#include <FindDirectory.h>
#include <File.h>
#include <Path.h>
#include <View.h>
#include <stdio.h>
#include "MouseSettings.h"
// The R5 settings file differs from that of OpenBeOS;
// the latter maps 16 different mouse buttons
#define R5_COMPATIBLE 1
static const bigtime_t kDefaultClickSpeed = 500000;
static const int32 kDefaultMouseSpeed = 65536;
static const int32 kDefaultMouseType = 3; // 3 button mouse
static const int32 kDefaultAccelerationFactor = 65536;
static const bool kDefaultAcceptFirstClick = false;
MouseSettings::MouseSettings()
:
fWindowPosition(-1, -1)
{
_RetrieveSettings();
fOriginalSettings = fSettings;
fOriginalMode = fMode;
fOriginalFocusFollowsMouseMode = fFocusFollowsMouseMode;
fOriginalAcceptFirstClick = fAcceptFirstClick;
}
MouseSettings::~MouseSettings()
{
_SaveSettings();
}
status_t
MouseSettings::_GetSettingsPath(BPath &path)
{
status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
if (status < B_OK)
return status;
path.Append(mouse_settings_file);
return B_OK;
}
void
MouseSettings::_RetrieveSettings()
{
// retrieve current values
if (get_mouse_map(&fSettings.map) != B_OK)
fprintf(stderr, "error when get_mouse_map\n");
if (get_click_speed(&fSettings.click_speed) != B_OK)
fprintf(stderr, "error when get_click_speed\n");
if (get_mouse_speed(&fSettings.accel.speed) != B_OK)
fprintf(stderr, "error when get_mouse_speed\n");
if (get_mouse_acceleration(&fSettings.accel.accel_factor) != B_OK)
fprintf(stderr, "error when get_mouse_acceleration\n");
if (get_mouse_type(&fSettings.type) != B_OK)
fprintf(stderr, "error when get_mouse_type\n");
fMode = mouse_mode();
fFocusFollowsMouseMode = focus_follows_mouse_mode();
fAcceptFirstClick = accept_first_click();
// also try to load the window position from disk
BPath path;
if (_GetSettingsPath(path) < B_OK)
return;
BFile file(path.Path(), B_READ_ONLY);
if (file.InitCheck() < B_OK)
return;
#if R5_COMPATIBLE
const off_t kOffset = sizeof(mouse_settings) - sizeof(mouse_map)
+ sizeof(int32) * 3;
// we have to do this because mouse_map counts 16 buttons in OBOS
#else
const off_t kOffset = sizeof(mouse_settings);
#endif
if (file.ReadAt(kOffset, &fWindowPosition, sizeof(BPoint))
!= sizeof(BPoint)) {
// set default window position (invalid positions will be
// corrected by the application; the window will be centered
// in this case)
fWindowPosition.x = -1;
fWindowPosition.y = -1;
}
#ifdef DEBUG
Dump();
#endif
}
status_t
MouseSettings::_SaveSettings()
{
BPath path;
status_t status = _GetSettingsPath(path);
if (status < B_OK)
return status;
BFile file(path.Path(), B_READ_WRITE | B_CREATE_FILE);
status = file.InitCheck();
if (status < B_OK)
return status;
#if R5_COMPATIBLE
const off_t kOffset = sizeof(mouse_settings) - sizeof(mouse_map)
+ sizeof(int32) * 3;
// we have to do this because mouse_map counts 16 buttons in OBOS
#else
const off_t kOffset = sizeof(mouse_settings);
#endif
file.WriteAt(kOffset, &fWindowPosition, sizeof(BPoint));
return B_OK;
}
#ifdef DEBUG
void
MouseSettings::Dump()
{
printf("type:\t\t%" B_PRId32 " button mouse\n", fSettings.type);
printf("map:\t\tleft = %" B_PRIu32 " : middle = %" B_PRIu32 " : right = %"
B_PRIu32 "\n", fSettings.map.button[0], fSettings.map.button[2],
fSettings.map.button[1]);
printf("click speed:\t%" B_PRId64 "\n", fSettings.click_speed);
printf("accel:\t\t%s\n", fSettings.accel.enabled ? "enabled" : "disabled");
printf("accel factor:\t%" B_PRId32 "\n", fSettings.accel.accel_factor);
printf("speed:\t\t%" B_PRId32 "\n", fSettings.accel.speed);
const char *mode = "unknown";
switch (fMode) {
case B_NORMAL_MOUSE:
mode = "click to focus and raise";
break;
case B_CLICK_TO_FOCUS_MOUSE:
mode = "click to focus";
break;
case B_FOCUS_FOLLOWS_MOUSE:
mode = "focus follows mouse";
break;
}
printf("mouse mode:\t%s\n", mode);
const char *focus_follows_mouse_mode = "unknown";
switch (fFocusFollowsMouseMode) {
case B_NORMAL_FOCUS_FOLLOWS_MOUSE:
focus_follows_mouse_mode = "normal";
break;
case B_WARP_FOCUS_FOLLOWS_MOUSE:
focus_follows_mouse_mode = "warp";
break;
case B_INSTANT_WARP_FOCUS_FOLLOWS_MOUSE:
focus_follows_mouse_mode = "instant warp";
break;
}
printf("focus follows mouse mode:\t%s\n", focus_follows_mouse_mode);
printf("accept first click:\t%s\n",
fAcceptFirstClick ? "enabled" : "disabled");
}
#endif
// Resets the settings to the system defaults
void
MouseSettings::Defaults()
{
SetClickSpeed(kDefaultClickSpeed);
SetMouseSpeed(kDefaultMouseSpeed);
SetMouseType(kDefaultMouseType);
SetAccelerationFactor(kDefaultAccelerationFactor);
SetMouseMode(B_NORMAL_MOUSE);
SetFocusFollowsMouseMode(B_NORMAL_FOCUS_FOLLOWS_MOUSE);
SetAcceptFirstClick(kDefaultAcceptFirstClick);
mouse_map map;
if (get_mouse_map(&map) == B_OK) {
map.button[0] = B_PRIMARY_MOUSE_BUTTON;
map.button[1] = B_SECONDARY_MOUSE_BUTTON;
map.button[2] = B_TERTIARY_MOUSE_BUTTON;
SetMapping(map);
}
}
// Checks if the settings are different then the system defaults
bool
MouseSettings::IsDefaultable()
{
return fSettings.click_speed != kDefaultClickSpeed
|| fSettings.accel.speed != kDefaultMouseSpeed
|| fSettings.type != kDefaultMouseType
|| fSettings.accel.accel_factor != kDefaultAccelerationFactor
|| fMode != B_NORMAL_MOUSE
|| fFocusFollowsMouseMode != B_NORMAL_FOCUS_FOLLOWS_MOUSE
|| fAcceptFirstClick != kDefaultAcceptFirstClick
|| fSettings.map.button[0] != B_PRIMARY_MOUSE_BUTTON
|| fSettings.map.button[1] != B_SECONDARY_MOUSE_BUTTON
|| fSettings.map.button[2] != B_TERTIARY_MOUSE_BUTTON;
}
// Reverts to the active settings at program startup
void
MouseSettings::Revert()
{
SetClickSpeed(fOriginalSettings.click_speed);
SetMouseSpeed(fOriginalSettings.accel.speed);
SetMouseType(fOriginalSettings.type);
SetAccelerationFactor(fOriginalSettings.accel.accel_factor);
SetMouseMode(fOriginalMode);
SetFocusFollowsMouseMode(fOriginalFocusFollowsMouseMode);
SetAcceptFirstClick(fOriginalAcceptFirstClick);
SetMapping(fOriginalSettings.map);
}
// Checks if the settings are different then the original settings
bool
MouseSettings::IsRevertable()
{
return fSettings.click_speed != fOriginalSettings.click_speed
|| fSettings.accel.speed != fOriginalSettings.accel.speed
|| fSettings.type != fOriginalSettings.type
|| fSettings.accel.accel_factor != fOriginalSettings.accel.accel_factor
|| fMode != fOriginalMode
|| fFocusFollowsMouseMode != fOriginalFocusFollowsMouseMode
|| fAcceptFirstClick != fOriginalAcceptFirstClick
|| fSettings.map.button[0] != fOriginalSettings.map.button[0]
|| fSettings.map.button[1] != fOriginalSettings.map.button[1]
|| fSettings.map.button[2] != fOriginalSettings.map.button[2];
}
void
MouseSettings::SetWindowPosition(BPoint corner)
{
fWindowPosition = corner;
}
void
MouseSettings::SetMouseType(int32 type)
{
if (set_mouse_type(type) == B_OK)
fSettings.type = type;
else
fprintf(stderr, "error when set_mouse_type\n");
}
bigtime_t
MouseSettings::ClickSpeed() const
{
return 1000000LL - fSettings.click_speed;
// to correct the Sliders 0-100000 scale
}
void
MouseSettings::SetClickSpeed(bigtime_t clickSpeed)
{
clickSpeed = 1000000LL - clickSpeed;
if (set_click_speed(clickSpeed) == B_OK)
fSettings.click_speed = clickSpeed;
else
fprintf(stderr, "error when set_click_speed\n");
}
void
MouseSettings::SetMouseSpeed(int32 speed)
{
if (set_mouse_speed(speed) == B_OK)
fSettings.accel.speed = speed;
else
fprintf(stderr, "error when set_mouse_speed\n");
}
void
MouseSettings::SetAccelerationFactor(int32 factor)
{
if (set_mouse_acceleration(factor) == B_OK)
fSettings.accel.accel_factor = factor;
else
fprintf(stderr, "error when set_mouse_acceleration\n");
}
uint32
MouseSettings::Mapping(int32 index) const
{
return fSettings.map.button[index];
}
void
MouseSettings::Mapping(mouse_map &map) const
{
map = fSettings.map;
}
void
MouseSettings::SetMapping(int32 index, uint32 button)
{
fSettings.map.button[index] = button;
if (set_mouse_map(&fSettings.map) != B_OK)
fprintf(stderr, "error when set_mouse_map\n");
}
void
MouseSettings::SetMapping(mouse_map &map)
{
if (set_mouse_map(&map) == B_OK)
fSettings.map = map;
else
fprintf(stderr, "error when set_mouse_map\n");
}
void
MouseSettings::SetMouseMode(mode_mouse mode)
{
set_mouse_mode(mode);
fMode = mode;
}
void
MouseSettings::SetFocusFollowsMouseMode(mode_focus_follows_mouse mode)
{
set_focus_follows_mouse_mode(mode);
fFocusFollowsMouseMode = mode;
}
void
MouseSettings::SetAcceptFirstClick(bool accept_first_click)
{
set_accept_first_click(accept_first_click);
fAcceptFirstClick = accept_first_click;
}

View File

@ -0,0 +1,78 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#ifndef MOUSE_SETTINGS_H
#define MOUSE_SETTINGS_H
#include <InterfaceDefs.h>
#include <Point.h>
#include <SupportDefs.h>
#include "kb_mouse_settings.h"
class BPath;
class MouseSettings {
public:
MouseSettings();
~MouseSettings();
void Revert();
bool IsRevertable();
void Defaults();
bool IsDefaultable();
void Dump();
BPoint WindowPosition() const { return fWindowPosition; }
void SetWindowPosition(BPoint corner);
int32 MouseType() const { return fSettings.type; }
void SetMouseType(int32 type);
bigtime_t ClickSpeed() const;
void SetClickSpeed(bigtime_t click_speed);
int32 MouseSpeed() const { return fSettings.accel.speed; }
void SetMouseSpeed(int32 speed);
int32 AccelerationFactor() const { return fSettings.accel.accel_factor; }
void SetAccelerationFactor(int32 factor);
uint32 Mapping(int32 index) const;
void Mapping(mouse_map &map) const;
void SetMapping(int32 index, uint32 button);
void SetMapping(mouse_map &map);
mode_mouse MouseMode() const { return fMode; }
void SetMouseMode(mode_mouse mode);
mode_focus_follows_mouse FocusFollowsMouseMode() const {
return fFocusFollowsMouseMode;
}
void SetFocusFollowsMouseMode(mode_focus_follows_mouse mode);
bool AcceptFirstClick() const { return fAcceptFirstClick; }
void SetAcceptFirstClick(bool accept_first_click);
private:
static status_t _GetSettingsPath(BPath &path);
void _RetrieveSettings();
status_t _SaveSettings();
mouse_settings fSettings, fOriginalSettings;
mode_mouse fMode, fOriginalMode;
mode_focus_follows_mouse fFocusFollowsMouseMode;
mode_focus_follows_mouse fOriginalFocusFollowsMouseMode;
bool fAcceptFirstClick, fOriginalAcceptFirstClick;
BPoint fWindowPosition;
};
#endif // MOUSE_SETTINGS_H

View File

@ -0,0 +1,380 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#include "MouseView.h"
#include <algorithm>
#include <Box.h>
#include <Button.h>
#include <Debug.h>
#include <GradientLinear.h>
#include <GradientRadial.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <PopUpMenu.h>
#include <Region.h>
#include <Shape.h>
#include <Slider.h>
#include <TextControl.h>
#include <TranslationUtils.h>
#include <TranslatorFormats.h>
#include <Window.h>
#include "InputConstants.h"
#include "MouseSettings.h"
#include "InputWindow.h"
static const int32 kButtonTop = 3;
static const int32 kMouseDownWidth = 72;
static const int32 kMouseDownHeight = 35;
static const int32 kOneButtonOffsets[4]
= { 0, kMouseDownWidth };
static const int32 kTwoButtonOffsets[4]
= { 0, kMouseDownWidth / 2, kMouseDownWidth };
static const int32 kThreeButtonOffsets[4]
= { 0, kMouseDownWidth / 3 + 1, kMouseDownWidth / 3 * 2, kMouseDownWidth };
static const rgb_color kButtonTextColor = { 0, 0, 0, 255 };
static const rgb_color kMouseShadowColor = { 100, 100, 100, 128 };
static const rgb_color kMouseBodyTopColor = { 0xed, 0xed, 0xed, 255 };
static const rgb_color kMouseBodyBottomColor = { 0x85, 0x85, 0x85, 255 };
static const rgb_color kMouseOutlineColor = { 0x51, 0x51, 0x51, 255 };
static const rgb_color kMouseButtonOutlineColor = { 0xa0, 0xa0, 0xa0, 255 };
static const rgb_color kButtonPressedColor = { 110, 110, 110, 110 };
static const int32*
getButtonOffsets(int32 type)
{
switch (type) {
case 1:
return kOneButtonOffsets;
case 2:
return kTwoButtonOffsets;
case 3:
default:
return kThreeButtonOffsets;
}
}
static uint32
getMappingNumber(int32 mapping)
{
switch (mapping) {
case B_PRIMARY_MOUSE_BUTTON:
return 0;
case B_SECONDARY_MOUSE_BUTTON:
return 1;
case B_TERTIARY_MOUSE_BUTTON:
return 2;
}
return 0;
}
MouseView::MouseView(const MouseSettings &settings)
:
BView("Mouse", B_PULSE_NEEDED | B_WILL_DRAW),
fSettings(settings),
fType(-1),
fButtons(0),
fOldButtons(0)
{
SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY);
fScaling = std::max(1.0f, be_plain_font->Size() / 12.0f);
}
MouseView::~MouseView()
{
}
void
MouseView::SetMouseType(int32 type)
{
fType = type;
Invalidate();
}
void
MouseView::MouseMapUpdated()
{
Invalidate();
}
void
MouseView::UpdateFromSettings()
{
SetMouseType(fSettings.MouseType());
}
void
MouseView::GetPreferredSize(float* _width, float* _height)
{
if (_width != NULL)
*_width = fScaling * (kMouseDownWidth + 2);
if (_height != NULL)
*_height = fScaling * 104;
}
void
MouseView::AttachedToWindow()
{
AdoptParentColors();
UpdateFromSettings();
_CreateButtonsPicture();
font_height fontHeight;
GetFontHeight(&fontHeight);
fDigitHeight = int32(ceilf(fontHeight.ascent) + ceilf(fontHeight.descent));
fDigitBaseline = int32(ceilf(fontHeight.ascent));
}
void
MouseView::MouseUp(BPoint)
{
fButtons = 0;
Invalidate(_ButtonsRect());
fOldButtons = fButtons;
}
void
MouseView::MouseDown(BPoint where)
{
BMessage *mouseMsg = Window()->CurrentMessage();
fButtons = mouseMsg->FindInt32("buttons");
int32 modifiers = mouseMsg->FindInt32("modifiers");
if (modifiers & B_CONTROL_KEY) {
if (modifiers & B_COMMAND_KEY)
fButtons = B_TERTIARY_MOUSE_BUTTON;
else
fButtons = B_SECONDARY_MOUSE_BUTTON;
}
// Get the current clipping region before requesting any updates.
// Otherwise those parts would be excluded from the region.
BRegion clipping;
GetClippingRegion(&clipping);
if (fOldButtons != fButtons) {
Invalidate(_ButtonsRect());
fOldButtons = fButtons;
}
const int32* offset = getButtonOffsets(fType);
int32 button = -1;
for (int32 i = 0; i <= fType; i++) {
if (_ButtonRect(offset, i).Contains(where)) {
button = i;
break;
}
}
if (button < 0)
return;
if (clipping.Contains(where)) {
button = _ConvertFromVisualOrder(button);
BPopUpMenu menu("Mouse Map Menu");
BMessage message(kMsgMouseMap);
message.AddInt32("button", button);
menu.AddItem(new BMenuItem("1", new BMessage(message)));
menu.AddItem(new BMenuItem("2", new BMessage(message)));
menu.AddItem(new BMenuItem("3", new BMessage(message)));
menu.ItemAt(getMappingNumber(fSettings.Mapping(button)))
->SetMarked(true);
menu.SetTargetForItems(Window());
ConvertToScreen(&where);
menu.Go(where, true);
}
}
void
MouseView::Draw(BRect updateFrame)
{
SetDrawingMode(B_OP_ALPHA);
SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
SetScale(fScaling * 1.8);
BShape mouseShape;
mouseShape.MoveTo(BPoint(16, 12));
// left
BPoint control[3] = { BPoint(12, 16), BPoint(8, 64), BPoint(32, 64) };
mouseShape.BezierTo(control);
// right
BPoint control2[3] = { BPoint(56, 64), BPoint(52, 16), BPoint(48, 12) };
mouseShape.BezierTo(control2);
// top
BPoint control3[3] = { BPoint(44, 8), BPoint(20, 8), BPoint(16, 12) };
mouseShape.BezierTo(control3);
mouseShape.Close();
// Draw the shadow
SetOrigin(-17 * fScaling, -11 * fScaling);
SetHighColor(kMouseShadowColor);
FillShape(&mouseShape, B_SOLID_HIGH);
// Draw the body
SetOrigin(-21 * fScaling, -14 * fScaling);
BGradientRadial bodyGradient(28, 24, 128);
bodyGradient.AddColor(kMouseBodyTopColor, 0);
bodyGradient.AddColor(kMouseBodyBottomColor, 255);
FillShape(&mouseShape, bodyGradient);
// Draw the outline
SetPenSize(1 / 1.8 / fScaling);
SetDrawingMode(B_OP_OVER);
SetHighColor(kMouseOutlineColor);
StrokeShape(&mouseShape, B_SOLID_HIGH);
// bottom button border
BShape buttonsOutline;
buttonsOutline.MoveTo(BPoint(13, 27));
BPoint control4[] = { BPoint(18, 30), BPoint(46, 30), BPoint(51, 27) };
buttonsOutline.BezierTo(control4);
SetHighColor(kMouseButtonOutlineColor);
StrokeShape(&buttonsOutline, B_SOLID_HIGH);
SetScale(1);
SetOrigin(0, 0);
// Separator between the buttons
const int32* offset = getButtonOffsets(fType);
for (int32 i = 1; i < fType; i++) {
BRect buttonRect = _ButtonRect(offset, i);
StrokeLine(buttonRect.LeftTop(), buttonRect.LeftBottom());
}
mouse_map map;
fSettings.Mapping(map);
SetDrawingMode(B_OP_OVER);
if (fButtons != 0)
ClipToPicture(&fButtonsPicture, B_ORIGIN, false);
for (int32 i = 0; i < fType; i++) {
// draw mapping number centered over the button
bool pressed = (fButtons & map.button[_ConvertFromVisualOrder(i)]) != 0;
// is button currently pressed?
if (pressed) {
SetDrawingMode(B_OP_ALPHA);
SetHighColor(kButtonPressedColor);
FillRect(_ButtonRect(offset, i));
}
BRect border(fScaling * (offset[i] + 1), fScaling * (kButtonTop + 5),
fScaling * offset[i + 1] - 1,
fScaling * (kButtonTop + kMouseDownHeight - 4));
if (i == 0)
border.left += fScaling * 5;
if (i == fType - 1)
border.right -= fScaling * 4;
char number[2] = {0};
number[0] = getMappingNumber(map.button[_ConvertFromVisualOrder(i)])
+ '1';
SetDrawingMode(B_OP_OVER);
SetHighColor(kButtonTextColor);
DrawString(number, BPoint(
border.left + (border.Width() - StringWidth(number)) / 2,
border.top + fDigitBaseline
+ (border.IntegerHeight() - fDigitHeight) / 2));
}
if (fButtons != 0)
ClipToPicture(NULL);
}
BRect
MouseView::_ButtonsRect() const
{
return BRect(0, fScaling * kButtonTop, fScaling * kMouseDownWidth,
fScaling * (kButtonTop + kMouseDownHeight));
}
BRect
MouseView::_ButtonRect(const int32* offsets, int index) const
{
return BRect(fScaling * offsets[index], fScaling * kButtonTop,
fScaling * offsets[index + 1] - 1,
fScaling * (kButtonTop + kMouseDownHeight));
}
int32
MouseView::_ConvertFromVisualOrder(int32 i)
{
if (fType < 3)
return i;
switch (i) {
case 0:
default:
return 0;
case 1:
return 2;
case 2:
return 1;
}
}
void
MouseView::_CreateButtonsPicture()
{
BeginPicture(&fButtonsPicture);
SetScale(1.8 * fScaling);
SetOrigin(-21 * fScaling, -14 * fScaling);
BShape mouseShape;
mouseShape.MoveTo(BPoint(48, 12));
// top
BPoint control3[3] = { BPoint(44, 8), BPoint(20, 8), BPoint(16, 12) };
mouseShape.BezierTo(control3);
// left
BPoint control[3] = { BPoint(12, 16), BPoint(13, 27), BPoint(13, 27) };
mouseShape.BezierTo(control);
// bottom
BPoint control4[3] = { BPoint(18, 30), BPoint(46, 30), BPoint(51, 27) };
mouseShape.BezierTo(control4);
// right
BPoint control2[3] = { BPoint(51, 27), BPoint(50, 14), BPoint(48, 12) };
mouseShape.BezierTo(control2);
mouseShape.Close();
SetHighColor(255, 0, 0, 255);
FillShape(&mouseShape, B_SOLID_HIGH);
EndPicture();
SetScale(1);
}

View File

@ -0,0 +1,63 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#ifndef MOUSE_VIEW_H
#define MOUSE_VIEW_H
#include <Bitmap.h>
#include <Picture.h>
#include <PopUpMenu.h>
#include <View.h>
class MouseSettings;
class MouseView : public BView {
public:
MouseView(const MouseSettings& settings);
virtual ~MouseView();
void SetMouseType(int32 type);
void MouseMapUpdated();
void UpdateFromSettings();
virtual void GetPreferredSize(float* _width, float* _height);
virtual void AttachedToWindow();
virtual void MouseUp(BPoint where);
virtual void MouseDown(BPoint where);
virtual void Draw(BRect frame);
bool IsMouseConnected()
{ return fConnected; }
private:
BRect _ButtonsRect() const;
BRect _ButtonRect(const int32* offsets,
int index) const;
int32 _ConvertFromVisualOrder(int32 button);
void _CreateButtonsPicture();
private:
typedef BView inherited;
const MouseSettings& fSettings;
BPicture fButtonsPicture;
int32 fDigitBaseline;
int32 fDigitHeight;
float fScaling;
int32 fType;
uint32 fButtons;
uint32 fOldButtons;
bool fConnected;
};
#endif /* MOUSE_VIEW_H */

View File

@ -0,0 +1,285 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#include "InputMouse.h"
#include <Bitmap.h>
#include <Box.h>
#include <Button.h>
#include <Catalog.h>
#include <ControlLook.h>
#include <Debug.h>
#include <InterfaceDefs.h>
#include <LayoutBuilder.h>
#include <Locale.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <PopUpMenu.h>
#include <SeparatorView.h>
#include <Slider.h>
#include <TextControl.h>
#include <TranslationUtils.h>
#include <Window.h>
#include "InputConstants.h"
#include "MouseSettings.h"
#include "MouseView.h"
static int32
mouse_mode_to_index(mode_mouse mode)
{
switch (mode) {
case B_NORMAL_MOUSE:
default:
return 0;
case B_CLICK_TO_FOCUS_MOUSE:
return 1;
case B_FOCUS_FOLLOWS_MOUSE:
return 2;
}
}
static int32
focus_follows_mouse_mode_to_index(mode_focus_follows_mouse mode)
{
switch (mode) {
case B_NORMAL_FOCUS_FOLLOWS_MOUSE:
default:
return 0;
case B_WARP_FOCUS_FOLLOWS_MOUSE:
return 1;
case B_INSTANT_WARP_FOCUS_FOLLOWS_MOUSE:
return 2;
}
}
// #pragma mark -
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "SettingsView"
SettingsView::SettingsView(MouseSettings& settings)
: BBox("main_view"),
fSettings(settings)
{
// Add the "Mouse Type" pop up menu
fTypeMenu = new BPopUpMenu("unknown");
fTypeMenu->AddItem(new BMenuItem(B_TRANSLATE("1-Button"),
new BMessage(kMsgMouseType)));
fTypeMenu->AddItem(new BMenuItem(B_TRANSLATE("2-Button"),
new BMessage(kMsgMouseType)));
fTypeMenu->AddItem(new BMenuItem(B_TRANSLATE("3-Button"),
new BMessage(kMsgMouseType)));
BMenuField* typeField = new BMenuField(B_TRANSLATE("Mouse type:"),
fTypeMenu);
typeField->SetAlignment(B_ALIGN_LEFT);
// Create the "Double-click speed slider...
fClickSpeedSlider = new BSlider("double_click_speed",
B_TRANSLATE("Double-click speed"), new BMessage(kMsgDoubleClickSpeed),
0, 1000, B_HORIZONTAL);
fClickSpeedSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
fClickSpeedSlider->SetHashMarkCount(7);
// Create the "Mouse Speed" slider...
fMouseSpeedSlider = new BSlider("mouse_speed", B_TRANSLATE("Mouse speed"),
new BMessage(kMsgMouseSpeed), 0, 1000, B_HORIZONTAL);
fMouseSpeedSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
fMouseSpeedSlider->SetHashMarkCount(7);
// Create the "Mouse Acceleration" slider...
fAccelerationSlider = new BSlider("mouse_acceleration",
B_TRANSLATE("Mouse acceleration"),
new BMessage(kMsgAccelerationFactor), 0, 1000, B_HORIZONTAL);
fAccelerationSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
fAccelerationSlider->SetHashMarkCount(7);
fMouseView = new MouseView(fSettings);
// Create the "Double-click test area" text box...
const char* label = B_TRANSLATE("Double-click test area");
BTextControl* doubleClickTextControl = new BTextControl(NULL,
label, NULL);
doubleClickTextControl->SetAlignment(B_ALIGN_LEFT, B_ALIGN_CENTER);
doubleClickTextControl->SetExplicitMinSize(
BSize(StringWidth(label), B_SIZE_UNSET));
// Add the "Mouse focus mode" pop up menu
fFocusMenu = new BPopUpMenu(B_TRANSLATE("Click to focus and raise"));
const char *focusLabels[] = {B_TRANSLATE_MARK("Click to focus and raise"),
B_TRANSLATE_MARK("Click to focus"),
B_TRANSLATE_MARK("Focus follows mouse")};
const mode_mouse focusModes[] = {B_NORMAL_MOUSE, B_CLICK_TO_FOCUS_MOUSE,
B_FOCUS_FOLLOWS_MOUSE};
for (int i = 0; i < 3; i++) {
BMessage* message = new BMessage(kMsgMouseFocusMode);
message->AddInt32("mode", focusModes[i]);
fFocusMenu->AddItem(new BMenuItem(B_TRANSLATE_NOCOLLECT(focusLabels[i]),
message));
}
BMenuField* focusField = new BMenuField(B_TRANSLATE("Focus mode:"),
fFocusMenu);
focusField->SetAlignment(B_ALIGN_LEFT);
// Add the "Focus follows mouse mode" pop up menu
fFocusFollowsMouseMenu = new BPopUpMenu(B_TRANSLATE("Normal"));
const char *focusFollowsMouseLabels[] = {B_TRANSLATE_MARK("Normal"),
B_TRANSLATE_MARK("Warp"), B_TRANSLATE_MARK("Instant warp")};
const mode_focus_follows_mouse focusFollowsMouseModes[]
= {B_NORMAL_FOCUS_FOLLOWS_MOUSE, B_WARP_FOCUS_FOLLOWS_MOUSE,
B_INSTANT_WARP_FOCUS_FOLLOWS_MOUSE};
for (int i = 0; i < 3; i++) {
BMessage* message = new BMessage(kMsgFollowsMouseMode);
message->AddInt32("mode_focus_follows_mouse",
focusFollowsMouseModes[i]);
fFocusFollowsMouseMenu->AddItem(new BMenuItem(
B_TRANSLATE_NOCOLLECT(focusFollowsMouseLabels[i]), message));
}
BMenuField* focusFollowsMouseField = new BMenuField(
"Focus follows mouse mode:", fFocusFollowsMouseMenu);
focusFollowsMouseField->SetAlignment(B_ALIGN_RIGHT);
// Add the "Click-through" check box
fAcceptFirstClickBox = new BCheckBox(B_TRANSLATE("Accept first click"),
new BMessage(kMsgAcceptFirstClick));
// Build the layout
// Layout is :
// A | B
// -----
// C
BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
// Horizontal : A|B
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
// Vertical block A: mouse type/view/test
.AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING)
.AddGroup(B_HORIZONTAL, 0)
.AddGlue()
.Add(typeField)
.AddGlue()
.End()
.AddGlue()
.AddGroup(B_HORIZONTAL, 0)
.AddGlue()
.Add(fMouseView)
.AddGlue()
.End()
.AddGlue()
.Add(doubleClickTextControl)
.End()
.Add(new BSeparatorView(B_VERTICAL))
// Vertical block B: speed settings
.AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING, 3)
.AddGroup(B_HORIZONTAL, 0)
.Add(fClickSpeedSlider)
.End()
.AddGroup(B_HORIZONTAL, 0)
.Add(fMouseSpeedSlider)
.End()
.AddGroup(B_HORIZONTAL, 0)
.Add(fAccelerationSlider)
.End()
.End()
.End()
.AddStrut(B_USE_DEFAULT_SPACING)
// Horizontal Block C: focus mode
.AddGroup(B_HORIZONTAL, B_USE_SMALL_SPACING)
.Add(focusField)
.AddGlue()
.AddGroup(B_VERTICAL, 0)
.Add(fAcceptFirstClickBox)
.End()
.End();
SetBorder(B_NO_BORDER);
}
SettingsView::~SettingsView()
{
}
void
SettingsView::AttachedToWindow()
{
UpdateFromSettings();
}
void
SettingsView::SetMouseType(int32 type)
{
fMouseView->SetMouseType(type);
}
void
SettingsView::MouseMapUpdated()
{
fMouseView->MouseMapUpdated();
}
void
SettingsView::UpdateFromSettings()
{
int32 value = int32(fSettings.ClickSpeed() / 1000);
// slow = 1000000, fast = 0
fClickSpeedSlider->SetValue(value);
value = int32((log(fSettings.MouseSpeed() / 8192.0) / log(2)) * 1000 / 6);
// slow = 8192, fast = 524287
fMouseSpeedSlider->SetValue(value);
value = int32(sqrt(fSettings.AccelerationFactor() / 16384.0) * 1000 / 4);
// slow = 0, fast = 262144
fAccelerationSlider->SetValue(value);
BMenuItem* item = fTypeMenu->ItemAt(fSettings.MouseType() - 1);
if (item != NULL)
item->SetMarked(true);
fMouseView->SetMouseType(fSettings.MouseType());
item = fFocusMenu->ItemAt(mouse_mode_to_index(fSettings.MouseMode()));
if (item != NULL)
item->SetMarked(true);
item = fFocusFollowsMouseMenu->ItemAt(
focus_follows_mouse_mode_to_index(fSettings.FocusFollowsMouseMode()));
if (item != NULL)
item->SetMarked(true);
fFocusFollowsMouseMenu->SetEnabled(fSettings.MouseMode()
== B_FOCUS_FOLLOWS_MOUSE);
fAcceptFirstClickBox->SetValue(fSettings.AcceptFirstClick()
? B_CONTROL_ON : B_CONTROL_OFF);
fAcceptFirstClickBox->SetEnabled(fSettings.MouseMode()
!= B_FOCUS_FOLLOWS_MOUSE);
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2019, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Preetpal Kaur <preetpalok123@gmail.com>
*/
#ifndef SETTINGS_VIEW_H
#define SETTINGS_VIEW_H
#include <Box.h>
#include <Bitmap.h>
#include <Button.h>
#include <CheckBox.h>
#include <Slider.h>
#include <PopUpMenu.h>
class MouseSettings;
class MouseView;
class SettingsView : public BBox {
public:
SettingsView(MouseSettings &settings);
virtual ~SettingsView();
virtual void AttachedToWindow();
void SetMouseType(int32 type);
void MouseMapUpdated();
void UpdateFromSettings();
BPopUpMenu* fFocusFollowsMouseMenu;
BCheckBox* fAcceptFirstClickBox;
private:
typedef BBox inherited;
const MouseSettings &fSettings;
BPopUpMenu* fTypeMenu;
BPopUpMenu* fFocusMenu;
MouseView* fMouseView;
BSlider* fClickSpeedSlider;
BSlider* fMouseSpeedSlider;
BSlider* fAccelerationSlider;
};
#endif /* SETTINGS_VIEW_H */