* 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),
fModifiers(0),
fDeadKey(0),
fIsDragging(false),
fDragKey(NULL),
fDropTarget(NULL)
{
fLayout = new KeyboardLayout;
@@ -125,7 +125,7 @@ void
KeyboardLayoutView::MouseDown(BPoint point)
{
fClickPoint = point;
fIsDragging = false;
fDragKey = NULL;
Key* key = _KeyAt(point);
if (key != NULL) {
@@ -138,8 +138,6 @@ KeyboardLayoutView::MouseDown(BPoint point)
void
KeyboardLayoutView::MouseUp(BPoint point)
{
fDropTarget = NULL;
Key* key = _KeyAt(fClickPoint);
if (key != NULL) {
fKeyState[key->code / 8] &= ~(1 << (7 - (key->code & 7)));
@@ -150,32 +148,9 @@ KeyboardLayoutView::MouseUp(BPoint point)
_InvalidateKey(key);
if (!fIsDragging && fKeymap != NULL) {
if (fDragKey == NULL && fKeymap != NULL) {
// Send fake key down message to target
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);
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);
_SendFakeKeyDown(key);
}
}
}
@@ -192,9 +167,13 @@ KeyboardLayoutView::MouseMoved(BPoint point, uint32 transit,
_InvalidateKey(fDropTarget);
fDropTarget = _KeyAt(point);
if (fDropTarget != NULL)
_InvalidateKey(fDropTarget);
} else if (!fIsDragging && (fabs(point.x - fClickPoint.x) > 4
if (fDropTarget != NULL) {
if (fDropTarget == fDragKey)
fDropTarget = NULL;
else
_InvalidateKey(fDropTarget);
}
} else if (fDragKey == NULL && (fabs(point.x - fClickPoint.x) > 4
|| fabs(point.y - fClickPoint.y) > 4)) {
// start dragging
Key* key = _KeyAt(fClickPoint);
@@ -240,7 +219,7 @@ KeyboardLayoutView::MouseMoved(BPoint point, uint32 transit,
}
DragMessage(&drag, bitmap, B_OP_ALPHA, offset);
fIsDragging = true;
fDragKey = key;
fKeyState[key->code / 8] &= ~(1 << (7 - (key->code & 7)));
_InvalidateKey(key);
@@ -263,24 +242,45 @@ KeyboardLayoutView::Draw(BRect updateRect)
void
KeyboardLayoutView::MessageReceived(BMessage* message)
{
if (message->WasDropped()) {
fDropTarget = NULL;
if (message->WasDropped() && fDropTarget != NULL && fKeymap != 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()));
if (key != NULL && fKeymap != 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--;
int32 keyCode;
if (!message->IsSourceRemote()
&& message->FindInt32("key", &keyCode) == B_OK) {
// switch keys if the dropped object came from us
Key* key = _KeyForCode(keyCode);
if (key == NULL || key == fDropTarget)
return;
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);
_InvalidateKey(key);
}
}
_InvalidateKey(fDropTarget);
fDropTarget = NULL;
}
switch (message->what) {
@@ -320,7 +320,7 @@ KeyboardLayoutView::_LayoutKeyboard()
void
KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, Key* key,
KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, const Key* key,
BRect rect, bool pressed)
{
rgb_color base = key->dark ? kDarkColor : kBrightColor;
@@ -471,7 +471,7 @@ KeyboardLayoutView::_FunctionKeyLabel(uint32 code, char* text, size_t textSize)
void
KeyboardLayoutView::_GetKeyLabel(Key* key, char* text, size_t textSize,
KeyboardLayoutView::_GetKeyLabel(const Key* key, char* text, size_t textSize,
key_kind& keyKind)
{
const key_map& map = fKeymap->Map();
@@ -555,7 +555,7 @@ KeyboardLayoutView::_InvalidateKey(int32 code)
void
KeyboardLayoutView::_InvalidateKey(Key* key)
KeyboardLayoutView::_InvalidateKey(const Key* key)
{
if (key != NULL)
Invalidate(_FrameFor(key));
@@ -586,7 +586,7 @@ KeyboardLayoutView::_HandleDeadKey(int32 key, int32 modifiers)
void
KeyboardLayoutView::_KeyChanged(BMessage* message)
KeyboardLayoutView::_KeyChanged(const BMessage* message)
{
const uint8* state;
ssize_t size;
@@ -649,7 +649,7 @@ KeyboardLayoutView::_KeyAt(BPoint point)
BRect
KeyboardLayoutView::_FrameFor(Key* key)
KeyboardLayoutView::_FrameFor(const Key* key)
{
BRect rect;
rect.left = key->frame.left * fFactor;
@@ -690,3 +690,34 @@ KeyboardLayoutView::_SetFontSize(BView* view, key_kind keyKind)
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 _DrawKey(BView* view, BRect updateRect, Key* key,
BRect frame, bool pressed);
void _DrawKey(BView* view, BRect updateRect,
const Key* key, BRect frame, bool pressed);
const char* _SpecialKeyLabel(const key_map& map, uint32 code);
const char* _SpecialMappedKeySymbol(const char* bytes,
size_t numBytes);
@@ -59,17 +59,18 @@ private:
size_t numBytes);
bool _FunctionKeyLabel(uint32 code, char* text,
size_t textSize);
void _GetKeyLabel(Key* key, char* text, size_t textSize,
key_kind& keyKind);
void _GetKeyLabel(const Key* key, char* text,
size_t textSize, key_kind& keyKind);
bool _IsKeyPressed(int32 code);
Key* _KeyForCode(int32 code);
void _InvalidateKey(int32 code);
void _InvalidateKey(Key* key);
void _InvalidateKey(const Key* key);
bool _HandleDeadKey(int32 key, int32 modifiers);
void _KeyChanged(BMessage* message);
void _KeyChanged(const BMessage* message);
Key* _KeyAt(BPoint point);
BRect _FrameFor(Key* key);
BRect _FrameFor(const Key* key);
void _SetFontSize(BView* view, key_kind keyKind);
void _SendFakeKeyDown(const Key* key);
KeyboardLayout* fLayout;
Keymap* fKeymap;
@@ -80,7 +81,7 @@ private:
int32 fDeadKey;
BPoint fClickPoint;
bool fIsDragging;
Key* fDragKey;
Key* fDropTarget;
BFont fFont;
+6
View File
@@ -445,6 +445,12 @@ Keymap::SetKey(uint32 keyCode, uint32 modifiers, int8 deadKey,
int32 oldNumBytes = fChars[offset];
if (oldNumBytes == numBytes
&& !memcmp(&fChars[offset + 1], bytes, numBytes)) {
// nothing to do
return;
}
// TODO: handle dead keys!
// TODO!
if (oldNumBytes != numBytes)
@@ -38,6 +38,10 @@ KeymapMessageFilter::Filter(BMessage* message, BHandler** /*_target*/)
if (fKeymap == NULL || message->what != B_KEY_DOWN)
return B_DISPATCH_MESSAGE;
void* keymap;
if (message->FindPointer("keymap", &keymap) == B_OK && keymap == fKeymap)
return B_DISPATCH_MESSAGE;
// TODO: add dead key handling!
int32 modifiers;