Removed all SettingsView stuff, and almost completely rewrote the MouseView class.

The mouse view code is now much cleaner and more generic.
Fixed all known remaining bugs.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5962 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-01-07 08:17:02 +00:00
parent 87e0ec1168
commit 7ed41b2f46
2 changed files with 187 additions and 303 deletions
+174 -281
View File
@@ -29,155 +29,129 @@
#include <Window.h>
#include "MouseView.h"
#include "MouseMessages.h"
#include "MouseWindow.h"
#include "MouseConstants.h"
#include "MouseBitmap.h"
#include "MouseSettings.h"
MouseView::MouseView(BRect rect, MouseSettings &settings)
: BBox(rect, "main_view"),
fCurrentButton(-1),
static const int32 kOneButtonOffsets[4] = {0, 55};
static const int32 kTwoButtonOffsets[4] = {0, 27, 55};
static const int32 kThreeButtonOffsets[4] = {0, 18, 36, 55};
static const int32 kButtonHeight = 26;
static const int32 kButtonTop = 6;
static const rgb_color kButtonPressedColor = {120, 120, 120};
static const rgb_color kButtonReleasedLeftColor = {255, 255, 255};
static const rgb_color kButtonReleasedRightColor = {184, 184, 184};
static const rgb_color kButtonPressedSeparatorColor = {48, 48, 48};
static const rgb_color kButtonReleasedSeparatorColor = {88, 88, 88};
static const rgb_color kButtonTextColor = {32, 32, 32};
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;
}
// #pragma mark -
MouseView::MouseView(BRect rect, const MouseSettings &settings)
: BView(rect, "mouse_view", B_FOLLOW_ALL, B_PULSE_NEEDED | B_WILL_DRAW),
fSettings(settings),
fType(-1),
fButtons(0),
fOldButtons(0)
{
ResizeTo(397 - 22, 293 - 55);
// ToDo: fixed values for now
fMouseBitmap = new BBitmap(BRect(0, 0, kMouseWidth - 1, kMouseHeight - 1), B_CMAP8);
fMouseBitmap->SetBits(kMouseBits, sizeof(kMouseBits), 0, kMouseColorSpace);
BTextControl *textcontrol;
BMenuField *menufield;
BRect frame;
fMouseDownBitmap = new BBitmap(BRect(0, 0, kMouseDownWidth - 1, kMouseDownHeight - 1), B_CMAP8);
fMouseDownBitmap->SetBits(kMouseDownBits, sizeof(kMouseDownBits), 0, kMouseDownColorSpace);
}
fDoubleClickBitmap = BTranslationUtils::GetBitmap("double_click_bmap");
fSpeedBitmap = BTranslationUtils::GetBitmap("speed_bmap");
fAccelerationBitmap = BTranslationUtils::GetBitmap("acceleration_bmap");
// i don't really understand this bitmap SetBits : i have to substract 4 lines and add 15 pixels
BRect mouseRect(0,0,kMouseWidth-1,kMouseHeight-5);
fMouseBitmap = new BBitmap(mouseRect, B_CMAP8);
fMouseBitmap->SetBits(kMouseBits, kMouseWidth*kMouseHeight + 15, 0, kMouseColorSpace);
BRect mouseDownRect(0,0,kMouseDownWidth-1,kMouseDownHeight-1);
fMouseDownBitmap = new BBitmap(mouseDownRect, B_CMAP8);
fMouseDownBitmap->SetBits(kMouseDownBits, kMouseDownWidth*kMouseDownHeight + 30, 0, kMouseDownColorSpace);
// Add the "Mouse Type" pop up menu
mouseTypeMenu = new BPopUpMenu("Mouse Type Menu");
mouseTypeMenu->AddItem(new BMenuItem("1-Button", new BMessage(POPUP_MOUSE_TYPE)));
mouseTypeMenu->AddItem(new BMenuItem("2-Button", new BMessage(POPUP_MOUSE_TYPE)));
mouseTypeMenu->AddItem(new BMenuItem("3-Button", new BMessage(POPUP_MOUSE_TYPE)));
frame.Set(7,8,208,20);
menufield = new BMenuField(frame, "mouse_type", "Mouse type", mouseTypeMenu);
menufield->SetDivider(menufield->Divider() - 29);
menufield->SetAlignment(B_ALIGN_RIGHT);
AddChild(menufield);
// Add the "Focus follows mouse" pop up menu
focusMenu = new BPopUpMenu("Focus Follows Mouse Menu");
focusMenu->AddItem(new BMenuItem("Disabled",new BMessage(POPUP_MOUSE_FOCUS)));
focusMenu->AddItem(new BMenuItem("Enabled",new BMessage(POPUP_MOUSE_FOCUS)));
focusMenu->AddItem(new BMenuItem("Warping",new BMessage(POPUP_MOUSE_FOCUS)));
focusMenu->AddItem(new BMenuItem("Instant-Warping",new BMessage(POPUP_MOUSE_FOCUS)));
frame.Set(165, 208, 440, 200);
menufield = new BMenuField(frame, "Focus follows mouse", "Focus follows mouse", focusMenu);
menufield->SetDivider(menufield->Divider() - 18);
menufield->SetAlignment(B_ALIGN_RIGHT);
AddChild(menufield);
// Create the "Double-click speed slider...
frame.Set(166, 11, 328, 50);
dcSpeedSlider = new BSlider(frame,"double_click_speed","Double-click speed",
new BMessage(SLIDER_DOUBLE_CLICK_SPEED), 0, 1000, B_BLOCK_THUMB, B_FOLLOW_LEFT, B_WILL_DRAW);
dcSpeedSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
dcSpeedSlider->SetHashMarkCount(5);
dcSpeedSlider->SetLimitLabels("Slow","Fast");
AddChild(dcSpeedSlider);
// Create the "Mouse Speed" slider...
frame.Set(166,76,328,125);
mouseSpeedSlider = new BSlider(frame,"mouse_speed","Mouse Speed",
new BMessage(SLIDER_MOUSE_SPEED),0,1000,B_BLOCK_THUMB,B_FOLLOW_LEFT,B_WILL_DRAW);
mouseSpeedSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
mouseSpeedSlider->SetHashMarkCount(7);
mouseSpeedSlider->SetLimitLabels("Slow","Fast");
AddChild(mouseSpeedSlider);
// Create the "Mouse Acceleration" slider...
frame.Set(166,141,328,190);
mouseAccSlider = new BSlider(frame,"mouse_acceleration","Mouse Acceleration",
new BMessage(SLIDER_MOUSE_ACC),0,1000,B_BLOCK_THUMB,B_FOLLOW_LEFT,B_WILL_DRAW);
mouseAccSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
mouseAccSlider->SetHashMarkCount(5);
mouseAccSlider->SetLimitLabels("Slow","Fast");
AddChild(mouseAccSlider);
// Create the "Double-click test area" text box...
frame=Bounds();
frame.left=frame.left+9;
frame.right=frame.right-230;
frame.top=frame.bottom-30;
textcontrol = new BTextControl(frame,"double_click_test_area",NULL,"Double-click test area", new BMessage(DOUBLE_CLICK_TEST_AREA),B_FOLLOW_LEFT,B_WILL_DRAW);
textcontrol->SetAlignment(B_ALIGN_LEFT,B_ALIGN_CENTER);
AddChild(textcontrol);
mouseMapMenu = new BPopUpMenu("Mouse Map Menu", true, true);
mouseMapMenu->AddItem(new BMenuItem("1", new BMessage(POPUP_MOUSE_MAP)));
mouseMapMenu->AddItem(new BMenuItem("2", new BMessage(POPUP_MOUSE_MAP)));
mouseMapMenu->AddItem(new BMenuItem("3", new BMessage(POPUP_MOUSE_MAP)));
void
MouseView::GetPreferredSize(float *_width, float *_height)
{
if (_width)
*_width = kMouseWidth;
if (_height)
*_height = kMouseHeight;
}
void
MouseView::MouseDown(BPoint where)
{
int32 index = mouseTypeMenu->IndexOf(mouseTypeMenu->FindMarked());
fCurrentButton = -1;
if ((index == 0) && BRect(50,41,105,73).Contains(where))
fCurrentButton = 0;
else if (index == 1) {
if(BRect(50,41,77,73).Contains(where))
fCurrentButton = 0;
else if (BRect(77,41,105,73).Contains(where))
fCurrentButton = 1;
} else {
if(BRect(50,41,68,73).Contains(where))
fCurrentButton = 0;
else if (BRect(86,41,105,73).Contains(where))
fCurrentButton = 1;
else if (BRect(68,41,86,73).Contains(where))
fCurrentButton = 2;
}
if (fCurrentButton >= 0) {
int32 number = 0;
switch (fCurrentMouseMap.button[fCurrentButton]) {
case B_PRIMARY_MOUSE_BUTTON: number = 0; break;
case B_SECONDARY_MOUSE_BUTTON: number = 1; break;
case B_TERTIARY_MOUSE_BUTTON: number = 2; break;
const int32 *offset = getButtonOffsets(fType);
int32 button = -1;
for (int32 i = 0; i <= fType; i++) {
BRect frame(offset[i], kButtonTop, offset[i + 1] - 1, kButtonTop + kButtonHeight);
if (frame.Contains(where)) {
button = i;
break;
}
mouseMapMenu->ItemAt(number)->SetMarked(true);
ConvertToScreen(&where);
mouseMapMenu->Go(where, true);
}
if (button < 0)
return;
button = ConvertFromVisualOrder(button);
BPopUpMenu menu("Mouse Map Menu");
BMessage message(POPUP_MOUSE_MAP);
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);
Invalidate();
}
void
MouseView::AttachedToWindow()
{
get_click_speed(&fClickSpeed);
get_mouse_speed(&fMouseSpeed);
get_mouse_acceleration(&fMouseAcc);
get_mouse_type(&fMouseType);
fMouseMode = mouse_mode();
get_mouse_map(&fMouseMap);
get_mouse_map(&fCurrentMouseMap);
Init();
if (Parent() != NULL)
SetViewColor(Parent()->ViewColor());
else
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
mouseMapMenu->SetTargetForItems(Window());
UpdateFromSettings();
}
@@ -188,8 +162,7 @@ MouseView::Pulse()
GetMouse(&point, &fButtons, true);
if (fOldButtons != fButtons) {
printf("buttons: old = %ld, new = %ld\n", fOldButtons, fButtons);
Invalidate();
Invalidate(BRect(0, kButtonTop, kMouseWidth, kButtonTop + kButtonHeight));
fOldButtons = fButtons;
}
}
@@ -200,172 +173,92 @@ MouseView::Draw(BRect updateFrame)
{
inherited::Draw(updateFrame);
SetHighColor(120,120,120);
SetLowColor(255,255,255);
// Line above the test area
StrokeLine(BPoint(8,198),BPoint(149,198),B_SOLID_HIGH);
StrokeLine(BPoint(8,199),BPoint(149,199),B_SOLID_LOW);
// Line above focus follows mouse
StrokeLine(BPoint(164,198),BPoint(367,198),B_SOLID_HIGH);
StrokeLine(BPoint(164,199),BPoint(367,199),B_SOLID_LOW);
// Line in the middle
StrokeLine(BPoint(156,10),BPoint(156,230),B_SOLID_HIGH);
StrokeLine(BPoint(157,11),BPoint(157,230),B_SOLID_LOW);
SetDrawingMode(B_OP_OVER);
// Draw the icons
if (updateFrame.Intersects( // i have to add 10 pixels width and height, so weird
BRect(333,16,354+fDoubleClickBitmap->Bounds().Width(),
165+fAccelerationBitmap->Bounds().Height()))) {
if (fDoubleClickBitmap != NULL)
DrawBitmapAsync(fDoubleClickBitmap, BPoint(344, 16));
if (fSpeedBitmap != NULL)
DrawBitmapAsync(fSpeedBitmap, BPoint(333, 90));
if (fAccelerationBitmap != NULL)
DrawBitmapAsync(fAccelerationBitmap, BPoint(333, 155));
// Draw the mouse top
DrawBitmapAsync(fMouseBitmap, updateFrame, updateFrame);
mouse_map map;
fSettings.Mapping(map);
const int32 *offset = getButtonOffsets(fType);
bool middlePressed = fType == 3 && (map.button[2] & fButtons) != 0;
for (int32 i = 0; i < fType; i++) {
BRect border(offset[i] + 1, kButtonTop + 2, offset[i + 1] - 1, kButtonTop + kButtonHeight - 2);
bool pressed = (fButtons & map.button[ConvertFromVisualOrder(i)]) != 0;
// is button currently pressed?
if (pressed) {
BRect frame(offset[i], 0, offset[i + 1], kMouseDownHeight + 1);
DrawBitmapAsync(fMouseDownBitmap, frame, frame.OffsetByCopy(0, kButtonTop));
}
if (i > 0 && fType > i) {
// left border
SetHighColor(pressed ? kButtonPressedColor : kButtonReleasedLeftColor);
StrokeLine(BPoint(border.LeftTop()), BPoint(border.LeftBottom()));
// draw separator
BRect separator = border.OffsetByCopy(-1, -1);
separator.bottom += 2;
SetHighColor(middlePressed ?
kButtonPressedSeparatorColor : kButtonReleasedSeparatorColor);
StrokeLine(BPoint(separator.LeftTop()), BPoint(separator.LeftBottom()));
}
if (fType > 1 && i + 1 < fType) {
// right border
SetHighColor(pressed ? kButtonPressedColor : kButtonReleasedRightColor);
StrokeLine(BPoint(border.RightTop()), BPoint(border.RightBottom()));
}
// draw mapping number centered over the button
SetHighColor(kButtonTextColor);
char number[2] = {0};
number[0] = getMappingNumber(map.button[ConvertFromVisualOrder(i)]) + '1';
DrawString(number,
BPoint(border.left + (border.Width() - StringWidth(number)) / 2, kButtonTop + 18));
}
// Draw the mouse
// i have to add 10 pixels width and height, so weird
if (updateFrame.Intersects(BRect(50,41,60+kMouseWidth,51+kMouseHeight))) {
SetDrawingMode(B_OP_OVER);
// Draw the mouse top
DrawBitmapAsync(fMouseBitmap,BPoint(50, 41));
int32 index = mouseTypeMenu->IndexOf(mouseTypeMenu->FindMarked());
if (index == 0) { // 1 button
if (fButtons & fCurrentMouseMap.button[0]) {
DrawBitmapAsync(fMouseDownBitmap,BPoint(50, 47));
SetHighColor(64,64,64);
}
} else if (index == 1) { // 2 button
if ( fButtons & fCurrentMouseMap.button[0]) {
DrawBitmapAsync(fMouseDownBitmap, BRect(0,0,27,28), BRect(50,47,77,75));
SetHighColor(120,120,120);
} else
SetHighColor(184,184,184);
StrokeLine(BPoint(76,49),BPoint(76,71),B_SOLID_HIGH);
if (fButtons & fCurrentMouseMap.button[1]) {
SetHighColor(120,120,120);
DrawBitmapAsync(fMouseDownBitmap, BRect(27,0,54,28), BRect(77,47,104,75));
} else
SetHighColor(255,255,255);
StrokeLine(BPoint(78,49),BPoint(78,71),B_SOLID_HIGH);
if ((fButtons & fCurrentMouseMap.button[0]) || (fButtons & fCurrentMouseMap.button[1]))
SetHighColor(48,48,48);
else
SetHighColor(88,88,88);
StrokeLine(BPoint(77,48),BPoint(77,72),B_SOLID_HIGH);
} else { // 3 button
if (fButtons & fCurrentMouseMap.button[0]) {
DrawBitmapAsync(fMouseDownBitmap, BRect(0,0,18,28), BRect(50,47,68,75));
SetHighColor(120,120,120);
} else
SetHighColor(184,184,184);
StrokeLine(BPoint(67,49),BPoint(67,71),B_SOLID_HIGH);
if (fButtons & fCurrentMouseMap.button[2]) {
DrawBitmapAsync(fMouseDownBitmap, BRect(18,0,36,28), BRect(68,47,86,75));
SetHighColor(120,120,120);
} else
SetHighColor(184,184,184);
StrokeLine(BPoint(85,49),BPoint(85,71),B_SOLID_HIGH);
if (fButtons & fCurrentMouseMap.button[2])
SetHighColor(120,120,120);
else
SetHighColor(255,255,255);
StrokeLine(BPoint(69,49),BPoint(69,71),B_SOLID_HIGH);
if (fButtons & fCurrentMouseMap.button[1]) {
DrawBitmapAsync(fMouseDownBitmap, BRect(36,0,54,28), BRect(86,47,104,75));
SetHighColor(120,120,120);
} else
SetHighColor(255,255,255);
StrokeLine(BPoint(87,49),BPoint(87,71),B_SOLID_HIGH);
if ((fButtons & fCurrentMouseMap.button[0]) || (fButtons & fCurrentMouseMap.button[2]))
SetHighColor(48,48,48);
else
SetHighColor(88,88,88);
StrokeLine(BPoint(68,48),BPoint(68,72),B_SOLID_HIGH);
if ((fButtons & fCurrentMouseMap.button[2]) || (fButtons & fCurrentMouseMap.button[1]))
SetHighColor(48,48,48);
else
SetHighColor(88,88,88);
StrokeLine(BPoint(86,48),BPoint(86,72),B_SOLID_HIGH);
}
SetHighColor(32,32,32);
SetFont(be_plain_font);
for(int32 i=0; i<index+1; i++) {
char number[2] = "1";
switch (fCurrentMouseMap.button[i]) {
case B_PRIMARY_MOUSE_BUTTON: *number = '1'; break;
case B_SECONDARY_MOUSE_BUTTON: *number = '2'; break;
case B_TERTIARY_MOUSE_BUTTON: *number = '3'; break;
}
int32 offsets[][3] = { {75},
{61, 88},
{57, 92, 74} };
MovePenTo(offsets[index][i], 65);
DrawString(number);
}
}
Sync();
SetDrawingMode(B_OP_COPY);
}
void
MouseView::Init()
int32
MouseView::ConvertFromVisualOrder(int32 i)
{
int32 value;
// slow = 1000000, fast = 0
value = (int32) ((1000000 - fClickSpeed) / 1000);
if (value > 1000) value = 1000;
if (value < 0) value = 0;
dcSpeedSlider->SetValue(value);
// slow = 8192, fast = 524287
value = (int32) (( log(fMouseSpeed / 8192) / log(2)) * 1000 / 6);
if (value > 1000) value = 1000;
if (value < 0) value = 0;
mouseSpeedSlider->SetValue(value);
// slow = 0, fast = 262144
value = (int32) (sqrt(fMouseAcc / 16384) * 1000 / 4);
if (value > 1000) value = 1000;
if (value < 0) value = 0;
mouseAccSlider->SetValue(value);
if (fMouseType < 1)
fMouseType = 1;
if (fMouseType > 3)
fMouseType = 3;
BMenuItem *item = mouseTypeMenu->ItemAt(fMouseType - 1);
if (item)
item->SetMarked(true);
int32 mode;
switch (fMouseMode) {
case B_NORMAL_MOUSE: mode = 0; break;
case B_FOCUS_FOLLOWS_MOUSE: mode = 1; break;
case B_WARP_MOUSE: mode = 2; break;
case B_INSTANT_WARP_MOUSE: mode = 3; break;
default : mode = 0; break;
if (fType < 3)
return i;
switch (i) {
case 0:
default:
return 0;
case 1:
return 2;
case 2:
return 1;
}
item = focusMenu->ItemAt(mode);
if (item)
item->SetMarked(true);
printf("click_speed : %lli, mouse_speed : %li, mouse_acc : %li, mouse_type : %li\n",
fClickSpeed, fMouseSpeed, fMouseAcc, fMouseType);
}
void
MouseView::SetMouseType(int32 type)
{
fType = type;
Invalidate();
}
void
MouseView::UpdateFromSettings()
{
SetMouseType(fSettings.MouseType());
}
+13 -22
View File
@@ -18,47 +18,38 @@
#define MOUSE_VIEW_H
#include <Box.h>
#include <View.h>
#include <Bitmap.h>
#include <Button.h>
#include <Slider.h>
#include <PopUpMenu.h>
class MouseSettings;
class MouseView : public BBox {
class MouseView : public BView {
public:
MouseView(BRect frame, MouseSettings &settings);
MouseView(BRect frame, const MouseSettings &settings);
virtual void AttachedToWindow();
virtual void MouseDown(BPoint where);
virtual void Draw(BRect frame);
virtual void Pulse();
virtual void GetPreferredSize(float *_width, float *_height);
void Init();
BSlider *dcSpeedSlider, *mouseSpeedSlider, *mouseAccSlider;
BPopUpMenu *mouseTypeMenu, *focusMenu, *mouseMapMenu;
bigtime_t fClickSpeed;
int32 fMouseSpeed;
int32 fMouseAcc;
int32 fMouseType;
mode_mouse fMouseMode;
mouse_map fMouseMap, fCurrentMouseMap;
int32 fCurrentButton;
void SetMouseType(int32 type);
void UpdateFromSettings();
private:
typedef BBox inherited;
int32 ConvertFromVisualOrder(int32 button);
MouseSettings &fSettings;
typedef BView inherited;
const MouseSettings &fSettings;
BBitmap *fMouseBitmap, *fMouseDownBitmap;
mouse_map fCurrentMouseMap;
int32 fType;
uint32 fButtons;
uint32 fOldButtons;
BBitmap *fDoubleClickBitmap, *fSpeedBitmap, *fAccelerationBitmap;
BBitmap *fMouseBitmap, *fMouseDownBitmap;
};
#endif /* MOUSE_VIEW_H */