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