* The message filter now does not do anything anymore when the source keymap

matches his own (field now added to the KeyboardLayoutView fake B_KEY_DOWN
  messages).
* The default action for keyboard to keyboard drag&drop is to switch the keys
  now.
* When a key is overwritten by a drop, the old key is now sent to the text
  view, so that it's not lost (if that was a mistake you can now easily revert
  it without having to press the "Revert" button and lose all changes).
* Cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29702 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-03-25 15:14:23 +00:00
parent 0699a8833e
commit 6aa7b63552
4 changed files with 101 additions and 59 deletions
+82 -51
View File
@@ -25,7 +25,7 @@ KeyboardLayoutView::KeyboardLayoutView(const char* name)
fKeymap(NULL), fKeymap(NULL),
fModifiers(0), fModifiers(0),
fDeadKey(0), fDeadKey(0),
fIsDragging(false), fDragKey(NULL),
fDropTarget(NULL) fDropTarget(NULL)
{ {
fLayout = new KeyboardLayout; fLayout = new KeyboardLayout;
@@ -125,7 +125,7 @@ void
KeyboardLayoutView::MouseDown(BPoint point) KeyboardLayoutView::MouseDown(BPoint point)
{ {
fClickPoint = point; fClickPoint = point;
fIsDragging = false; fDragKey = NULL;
Key* key = _KeyAt(point); Key* key = _KeyAt(point);
if (key != NULL) { if (key != NULL) {
@@ -138,8 +138,6 @@ KeyboardLayoutView::MouseDown(BPoint point)
void void
KeyboardLayoutView::MouseUp(BPoint point) KeyboardLayoutView::MouseUp(BPoint point)
{ {
fDropTarget = NULL;
Key* key = _KeyAt(fClickPoint); Key* key = _KeyAt(fClickPoint);
if (key != NULL) { if (key != NULL) {
fKeyState[key->code / 8] &= ~(1 << (7 - (key->code & 7))); fKeyState[key->code / 8] &= ~(1 << (7 - (key->code & 7)));
@@ -150,32 +148,9 @@ KeyboardLayoutView::MouseUp(BPoint point)
_InvalidateKey(key); _InvalidateKey(key);
if (!fIsDragging && fKeymap != NULL) { if (fDragKey == NULL && fKeymap != NULL) {
// Send fake key down message to target // Send fake key down message to target
BMessage message(B_KEY_DOWN); _SendFakeKeyDown(key);
message.AddInt64("when", system_time());
message.AddData("states", B_UINT8_TYPE, &fKeyState,
sizeof(fKeyState));
message.AddInt32("key", key->code);
message.AddInt32("modifiers", fModifiers);
char* string;
int32 numBytes;
fKeymap->GetChars(key->code, fModifiers, fDeadKey, &string,
&numBytes);
if (string != NULL) {
message.AddString("bytes", string);
delete[] string;
}
fKeymap->GetChars(key->code, 0, 0, &string, &numBytes);
if (string != NULL) {
message.AddInt32("raw_char", string[0]);
message.AddInt8("byte", string[0]);
delete[] string;
}
fTarget.SendMessage(&message);
} }
} }
} }
@@ -192,9 +167,13 @@ KeyboardLayoutView::MouseMoved(BPoint point, uint32 transit,
_InvalidateKey(fDropTarget); _InvalidateKey(fDropTarget);
fDropTarget = _KeyAt(point); fDropTarget = _KeyAt(point);
if (fDropTarget != NULL) if (fDropTarget != NULL) {
_InvalidateKey(fDropTarget); if (fDropTarget == fDragKey)
} else if (!fIsDragging && (fabs(point.x - fClickPoint.x) > 4 fDropTarget = NULL;
else
_InvalidateKey(fDropTarget);
}
} else if (fDragKey == NULL && (fabs(point.x - fClickPoint.x) > 4
|| fabs(point.y - fClickPoint.y) > 4)) { || fabs(point.y - fClickPoint.y) > 4)) {
// start dragging // start dragging
Key* key = _KeyAt(fClickPoint); Key* key = _KeyAt(fClickPoint);
@@ -240,7 +219,7 @@ KeyboardLayoutView::MouseMoved(BPoint point, uint32 transit,
} }
DragMessage(&drag, bitmap, B_OP_ALPHA, offset); DragMessage(&drag, bitmap, B_OP_ALPHA, offset);
fIsDragging = true; fDragKey = key;
fKeyState[key->code / 8] &= ~(1 << (7 - (key->code & 7))); fKeyState[key->code / 8] &= ~(1 << (7 - (key->code & 7)));
_InvalidateKey(key); _InvalidateKey(key);
@@ -263,24 +242,45 @@ KeyboardLayoutView::Draw(BRect updateRect)
void void
KeyboardLayoutView::MessageReceived(BMessage* message) KeyboardLayoutView::MessageReceived(BMessage* message)
{ {
if (message->WasDropped()) { if (message->WasDropped() && fDropTarget != NULL && fKeymap != NULL) {
fDropTarget = NULL; const char* data;
ssize_t size;
if (message->FindData("text/plain", B_MIME_DATA,
(const void**)&data, &size) == B_OK) {
// ignore trailing null bytes
if (data[size - 1] == '\0')
size--;
Key* key = _KeyAt(ConvertFromScreen(message->DropPoint())); int32 keyCode;
if (key != NULL && fKeymap != NULL) { if (!message->IsSourceRemote()
const char* data; && message->FindInt32("key", &keyCode) == B_OK) {
ssize_t size; // switch keys if the dropped object came from us
if (message->FindData("text/plain", B_MIME_DATA, Key* key = _KeyForCode(keyCode);
(const void**)&data, &size) == B_OK) { if (key == NULL || key == fDropTarget)
// ignore trailing null bytes return;
if (data[size - 1] == '\0')
size--;
fKeymap->SetKey(key->code, fModifiers, fDeadKey, char* string;
int32 numBytes;
fKeymap->GetChars(fDropTarget->code, fModifiers, fDeadKey,
&string, &numBytes);
if (string != NULL) {
fKeymap->SetKey(fDropTarget->code, fModifiers, fDeadKey,
(const char*)data, size);
fKeymap->SetKey(key->code, fModifiers, fDeadKey,
string, numBytes);
delete[] string;
}
} else {
// Send the old key to the target, so it's not lost entirely
_SendFakeKeyDown(fDropTarget);
fKeymap->SetKey(fDropTarget->code, fModifiers, fDeadKey,
(const char*)data, size); (const char*)data, size);
_InvalidateKey(key);
} }
} }
_InvalidateKey(fDropTarget);
fDropTarget = NULL;
} }
switch (message->what) { switch (message->what) {
@@ -320,7 +320,7 @@ KeyboardLayoutView::_LayoutKeyboard()
void void
KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, Key* key, KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, const Key* key,
BRect rect, bool pressed) BRect rect, bool pressed)
{ {
rgb_color base = key->dark ? kDarkColor : kBrightColor; rgb_color base = key->dark ? kDarkColor : kBrightColor;
@@ -471,7 +471,7 @@ KeyboardLayoutView::_FunctionKeyLabel(uint32 code, char* text, size_t textSize)
void void
KeyboardLayoutView::_GetKeyLabel(Key* key, char* text, size_t textSize, KeyboardLayoutView::_GetKeyLabel(const Key* key, char* text, size_t textSize,
key_kind& keyKind) key_kind& keyKind)
{ {
const key_map& map = fKeymap->Map(); const key_map& map = fKeymap->Map();
@@ -555,7 +555,7 @@ KeyboardLayoutView::_InvalidateKey(int32 code)
void void
KeyboardLayoutView::_InvalidateKey(Key* key) KeyboardLayoutView::_InvalidateKey(const Key* key)
{ {
if (key != NULL) if (key != NULL)
Invalidate(_FrameFor(key)); Invalidate(_FrameFor(key));
@@ -586,7 +586,7 @@ KeyboardLayoutView::_HandleDeadKey(int32 key, int32 modifiers)
void void
KeyboardLayoutView::_KeyChanged(BMessage* message) KeyboardLayoutView::_KeyChanged(const BMessage* message)
{ {
const uint8* state; const uint8* state;
ssize_t size; ssize_t size;
@@ -649,7 +649,7 @@ KeyboardLayoutView::_KeyAt(BPoint point)
BRect BRect
KeyboardLayoutView::_FrameFor(Key* key) KeyboardLayoutView::_FrameFor(const Key* key)
{ {
BRect rect; BRect rect;
rect.left = key->frame.left * fFactor; rect.left = key->frame.left * fFactor;
@@ -690,3 +690,34 @@ KeyboardLayoutView::_SetFontSize(BView* view, key_kind keyKind)
break; break;
} }
} }
void
KeyboardLayoutView::_SendFakeKeyDown(const Key* key)
{
BMessage message(B_KEY_DOWN);
message.AddInt64("when", system_time());
message.AddData("states", B_UINT8_TYPE, &fKeyState,
sizeof(fKeyState));
message.AddInt32("key", key->code);
message.AddInt32("modifiers", fModifiers);
message.AddPointer("keymap", fKeymap);
char* string;
int32 numBytes;
fKeymap->GetChars(key->code, fModifiers, fDeadKey, &string,
&numBytes);
if (string != NULL) {
message.AddString("bytes", string);
delete[] string;
}
fKeymap->GetChars(key->code, 0, 0, &string, &numBytes);
if (string != NULL) {
message.AddInt32("raw_char", string[0]);
message.AddInt8("byte", string[0]);
delete[] string;
}
fTarget.SendMessage(&message);
}
+9 -8
View File
@@ -50,8 +50,8 @@ private:
}; };
void _LayoutKeyboard(); void _LayoutKeyboard();
void _DrawKey(BView* view, BRect updateRect, Key* key, void _DrawKey(BView* view, BRect updateRect,
BRect frame, bool pressed); const Key* key, BRect frame, bool pressed);
const char* _SpecialKeyLabel(const key_map& map, uint32 code); const char* _SpecialKeyLabel(const key_map& map, uint32 code);
const char* _SpecialMappedKeySymbol(const char* bytes, const char* _SpecialMappedKeySymbol(const char* bytes,
size_t numBytes); size_t numBytes);
@@ -59,17 +59,18 @@ private:
size_t numBytes); size_t numBytes);
bool _FunctionKeyLabel(uint32 code, char* text, bool _FunctionKeyLabel(uint32 code, char* text,
size_t textSize); size_t textSize);
void _GetKeyLabel(Key* key, char* text, size_t textSize, void _GetKeyLabel(const Key* key, char* text,
key_kind& keyKind); size_t textSize, key_kind& keyKind);
bool _IsKeyPressed(int32 code); bool _IsKeyPressed(int32 code);
Key* _KeyForCode(int32 code); Key* _KeyForCode(int32 code);
void _InvalidateKey(int32 code); void _InvalidateKey(int32 code);
void _InvalidateKey(Key* key); void _InvalidateKey(const Key* key);
bool _HandleDeadKey(int32 key, int32 modifiers); bool _HandleDeadKey(int32 key, int32 modifiers);
void _KeyChanged(BMessage* message); void _KeyChanged(const BMessage* message);
Key* _KeyAt(BPoint point); Key* _KeyAt(BPoint point);
BRect _FrameFor(Key* key); BRect _FrameFor(const Key* key);
void _SetFontSize(BView* view, key_kind keyKind); void _SetFontSize(BView* view, key_kind keyKind);
void _SendFakeKeyDown(const Key* key);
KeyboardLayout* fLayout; KeyboardLayout* fLayout;
Keymap* fKeymap; Keymap* fKeymap;
@@ -80,7 +81,7 @@ private:
int32 fDeadKey; int32 fDeadKey;
BPoint fClickPoint; BPoint fClickPoint;
bool fIsDragging; Key* fDragKey;
Key* fDropTarget; Key* fDropTarget;
BFont fFont; BFont fFont;
+6
View File
@@ -445,6 +445,12 @@ Keymap::SetKey(uint32 keyCode, uint32 modifiers, int8 deadKey,
int32 oldNumBytes = fChars[offset]; int32 oldNumBytes = fChars[offset];
if (oldNumBytes == numBytes
&& !memcmp(&fChars[offset + 1], bytes, numBytes)) {
// nothing to do
return;
}
// TODO: handle dead keys! // TODO: handle dead keys!
// TODO! // TODO!
if (oldNumBytes != numBytes) if (oldNumBytes != numBytes)
@@ -38,6 +38,10 @@ KeymapMessageFilter::Filter(BMessage* message, BHandler** /*_target*/)
if (fKeymap == NULL || message->what != B_KEY_DOWN) if (fKeymap == NULL || message->what != B_KEY_DOWN)
return B_DISPATCH_MESSAGE; return B_DISPATCH_MESSAGE;
void* keymap;
if (message->FindPointer("keymap", &keymap) == B_OK && keymap == fKeymap)
return B_DISPATCH_MESSAGE;
// TODO: add dead key handling! // TODO: add dead key handling!
int32 modifiers; int32 modifiers;