From 8ba65ba1b4e7129240fe6756087e600e6952efa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 24 Mar 2009 09:45:32 +0000 Subject: [PATCH] * Another work-in-progress commit: added dead key handling, started mouse interaction, draw symbols differently. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29672 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/preferences/keymap/KeyboardLayoutView.cpp | 199 +++++++++++++----- src/preferences/keymap/KeyboardLayoutView.h | 45 ++-- 2 files changed, 176 insertions(+), 68 deletions(-) diff --git a/src/preferences/keymap/KeyboardLayoutView.cpp b/src/preferences/keymap/KeyboardLayoutView.cpp index 76c243afb6..2302e74574 100644 --- a/src/preferences/keymap/KeyboardLayoutView.cpp +++ b/src/preferences/keymap/KeyboardLayoutView.cpp @@ -107,12 +107,24 @@ KeyboardLayoutView::KeyUp(const char* bytes, int32 numBytes) void KeyboardLayoutView::MouseDown(BPoint point) { + fClickPoint = point; + + Key* key = _KeyAt(point); + if (key != NULL) { + fKeyState[key->code / 8] |= (1 << (7 - (key->code & 7))); + _InvalidateKey(key->code); + } } void KeyboardLayoutView::MouseUp(BPoint point) { + Key* key = _KeyAt(fClickPoint); + if (key != NULL) { + fKeyState[key->code / 8] &= ~(1 << (7 - (key->code & 7))); + _InvalidateKey(key->code); + } } @@ -126,33 +138,52 @@ KeyboardLayoutView::MouseMoved(BPoint point, uint32 transit, void KeyboardLayoutView::Draw(BRect updateRect) { - rgb_color brightColor = {230, 230, 230}; - rgb_color darkColor = {200, 200, 200}; + static const rgb_color kBrightColor = {230, 230, 230}; + static const rgb_color kDarkColor = {200, 200, 200}; + static const rgb_color kSecondDeadKeyColor = {130, 180, 230}; + static const rgb_color kDeadKeyColor = {240, 240, 150}; for (int32 i = 0; i < fLayout->CountKeys(); i++) { Key* key = fLayout->KeyAt(i); BRect rect = _FrameFor(key); - rgb_color base = key->dark ? darkColor : brightColor; + rgb_color base = key->dark ? kDarkColor : kBrightColor; bool pressed = _IsKeyPressed(key->code); - bool special = false; + key_kind keyKind = kNormalKey; + int32 deadKey = 0; + bool secondDeadKey; char text[32]; if (fKeymap != NULL) { - _GetKeyLabel(key, text, sizeof(text), special); + _GetKeyLabel(key, text, sizeof(text), keyKind); + deadKey = fKeymap->IsDeadKey(key->code, fModifiers); + secondDeadKey = fKeymap->IsDeadSecondKey(key->code, fModifiers, + fDeadKey); } else { // Show the key code if there is no keymap snprintf(text, sizeof(text), "%02lx", key->code); } - if (special) { - fSpecialFont.SetSize(_FontSizeFor(rect, text) * 0.8); - SetFont(&fSpecialFont); - } else { - fFont.SetSize(_FontSizeFor(rect, text)); - SetFont(&fFont); + switch (keyKind) { + case kNormalKey: + fFont.SetSize(_FontSizeFor(rect, text)); + SetFont(&fFont); + break; + case kSpecialKey: + fSpecialFont.SetSize(_FontSizeFor(rect, text) * 0.7); + SetFont(&fSpecialFont); + break; + case kSymbolKey: + fSpecialFont.SetSize(_FontSizeFor(rect, text) * 1.6); + SetFont(&fSpecialFont); + break; } + if (secondDeadKey) + base = kSecondDeadKeyColor; + else if (deadKey > 0) + base = kDeadKeyColor; + if (key->shape == kRectangleKeyShape) { be_control_look->DrawButtonFrame(this, rect, updateRect, base, pressed ? BControlLook::B_ACTIVATED : 0); @@ -168,16 +199,16 @@ KeyboardLayoutView::Draw(BRect updateRect) // TODO: make better! rect.bottom -= 20; be_control_look->DrawButtonBackground(this, rect, updateRect, - key->dark ? darkColor : brightColor, 0, - BControlLook::B_LEFT_BORDER | BControlLook::B_RIGHT_BORDER + base, 0, BControlLook::B_LEFT_BORDER + | BControlLook::B_RIGHT_BORDER | BControlLook::B_TOP_BORDER); rect = _FrameFor(key); rect.top += 20; rect.left += 10; be_control_look->DrawButtonBackground(this, rect, updateRect, - key->dark ? darkColor : brightColor, 0, - BControlLook::B_LEFT_BORDER | BControlLook::B_RIGHT_BORDER + base, 0, BControlLook::B_LEFT_BORDER + | BControlLook::B_RIGHT_BORDER | BControlLook::B_BOTTOM_BORDER); } } @@ -206,7 +237,7 @@ KeyboardLayoutView::MessageReceived(BMessage* message) const char* -KeyboardLayoutView::_ModifierKeyLabel(const key_map& map, uint32 code) +KeyboardLayoutView::_SpecialKeyLabel(const key_map& map, uint32 code) { if (code == map.caps_key) return "CAPS LOCK"; @@ -224,19 +255,21 @@ KeyboardLayoutView::_ModifierKeyLabel(const key_map& map, uint32 code) return "OPTION"; if (code == map.menu_key) return "MENU"; + if (code == B_PRINT_KEY) + return "PRINT"; + if (code == B_PAUSE_KEY) + return "PAUSE"; return NULL; } const char* -KeyboardLayoutView::_SpecialKeyLabel(const char* bytes, size_t numBytes) +KeyboardLayoutView::_SpecialMappedKeySymbol(const char* bytes, size_t numBytes) { if (numBytes != 1) return NULL; - if (bytes[0] == B_ESCAPE) - return "ESC"; if (bytes[0] == B_TAB) return "\xe2\x86\xb9"; if (bytes[0] == B_ENTER) @@ -244,19 +277,6 @@ KeyboardLayoutView::_SpecialKeyLabel(const char* bytes, size_t numBytes) if (bytes[0] == B_BACKSPACE) return "back";//\xe2\x86\x92"; - if (bytes[0] == B_INSERT) - return "INS"; - if (bytes[0] == B_DELETE) - return "DEL"; - if (bytes[0] == B_HOME) - return "HOME"; - if (bytes[0] == B_END) - return "END"; - if (bytes[0] == B_PAGE_UP) - return "PAGE \xe2\x86\x91"; - if (bytes[0] == B_PAGE_DOWN) - return "PAGE \xe2\x86\x93"; - if (bytes[0] == B_UP_ARROW) return "\xe2\x86\x91"; if (bytes[0] == B_LEFT_ARROW) @@ -270,15 +290,39 @@ KeyboardLayoutView::_SpecialKeyLabel(const char* bytes, size_t numBytes) } -bool -KeyboardLayoutView::_FunctionKeyLabel(const char* bytes, size_t numBytes, - char* text, size_t textSize) +const char* +KeyboardLayoutView::_SpecialMappedKeyLabel(const char* bytes, size_t numBytes) { - if (bytes[0] != B_FUNCTION_KEY) - return false; + if (numBytes != 1) + return NULL; - if (bytes[1] >= B_F1_KEY && bytes[1] <= B_F12_KEY) { - snprintf(text, textSize, "F%d", bytes[1] + 1 - B_F1_KEY); + if (bytes[0] == B_ESCAPE) + return "ESC"; + if (bytes[0] == B_BACKSPACE) + return "BACKSPACE"; + + if (bytes[0] == B_INSERT) + return "INS"; + if (bytes[0] == B_DELETE) + return "DEL"; + if (bytes[0] == B_HOME) + return "HOME"; + if (bytes[0] == B_END) + return "END"; + if (bytes[0] == B_PAGE_UP) + return "PAGE \xe2\x86\x91"; + if (bytes[0] == B_PAGE_DOWN) + return "PAGE \xe2\x86\x93"; + + return NULL; +} + + +bool +KeyboardLayoutView::_FunctionKeyLabel(uint32 code, char* text, size_t textSize) +{ + if (code >= B_F1_KEY && code <= B_F12_KEY) { + snprintf(text, textSize, "F%ld", code + 1 - B_F1_KEY); return true; } @@ -288,16 +332,21 @@ KeyboardLayoutView::_FunctionKeyLabel(const char* bytes, size_t numBytes, void KeyboardLayoutView::_GetKeyLabel(Key* key, char* text, size_t textSize, - bool& specialKey) + key_kind& keyKind) { const key_map& map = fKeymap->Map(); - specialKey = false; + keyKind = kNormalKey; text[0] = '\0'; - const char* modifier = _ModifierKeyLabel(map, key->code); - if (modifier != NULL) { - strlcpy(text, modifier, textSize); - specialKey = true; + const char* special = _SpecialKeyLabel(map, key->code); + if (special != NULL) { + strlcpy(text, special, textSize); + keyKind = kSpecialKey; + return; + } + + if (_FunctionKeyLabel(key->code, text, textSize)) { + keyKind = kSpecialKey; return; } @@ -306,14 +355,17 @@ KeyboardLayoutView::_GetKeyLabel(Key* key, char* text, size_t textSize, fKeymap->GetChars(key->code, fModifiers, fDeadKey, &bytes, &numBytes); if (bytes != NULL) { - const char* special = _SpecialKeyLabel(bytes, numBytes); + special = _SpecialMappedKeyLabel(bytes, numBytes); if (special != NULL) { strlcpy(text, special, textSize); - specialKey = true; + keyKind = kSpecialKey; return; } - if (_FunctionKeyLabel(bytes, numBytes, text, textSize)) { - specialKey = true; + + special = _SpecialMappedKeySymbol(bytes, numBytes); + if (special != NULL) { + strlcpy(text, special, textSize); + keyKind = kSymbolKey; return; } @@ -341,7 +393,7 @@ Key* KeyboardLayoutView::_KeyForCode(int32 code) { // TODO: have a lookup array - + for (int32 i = 0; i < fLayout->CountKeys(); i++) { Key* key = fLayout->KeyAt(i); if (key->code == code) @@ -366,17 +418,37 @@ KeyboardLayoutView::_KeyChanged(BMessage* message) { const uint8* state; ssize_t size; + int32 key; if (message->FindData("states", B_UINT8_TYPE, (const void**)&state, &size) - != B_OK) + != B_OK + || message->FindInt32("key", &key) != B_OK) return; // Update key state, and invalidate change keys + bool checkSingle = true; + + if (message->what == B_KEY_DOWN || message->what == B_UNMAPPED_KEY_DOWN) { + int32 deadKey = fKeymap->IsDeadKey(key, fModifiers); + if (fDeadKey != deadKey) { + Invalidate(); + fDeadKey = deadKey; + checkSingle = false; + } else if (fDeadKey != 0) { + Invalidate(); + fDeadKey = 0; + checkSingle = false; + } + } + for (int32 i = 0; i < 16; i++) { if (fKeyState[i] != state[i]) { uint8 diff = fKeyState[i] ^ state[i]; fKeyState[i] = state[i]; + if (!checkSingle) + continue; + for (int32 j = 7; diff != 0; j--, diff >>= 1) { if (diff & 1) { _InvalidateKey(i * 8 + j); @@ -387,6 +459,31 @@ KeyboardLayoutView::_KeyChanged(BMessage* message) } +Key* +KeyboardLayoutView::_KeyAt(BPoint point) +{ + // Find key candidate + + BPoint keyPoint = point; + keyPoint -= fOffset; + keyPoint.x /= fFactor; + keyPoint.y /= fFactor; + + for (int32 i = 0; i < fLayout->CountKeys(); i++) { + Key* key = fLayout->KeyAt(i); + if (key->frame.Contains(keyPoint)) { + BRect frame = _FrameFor(key); + if (frame.Contains(point)) + return key; + + return NULL; + } + } + + return NULL; +} + + BRect KeyboardLayoutView::_FrameFor(Key* key) { diff --git a/src/preferences/keymap/KeyboardLayoutView.h b/src/preferences/keymap/KeyboardLayoutView.h index 3f3133d5b7..056cbdba1b 100644 --- a/src/preferences/keymap/KeyboardLayoutView.h +++ b/src/preferences/keymap/KeyboardLayoutView.h @@ -37,34 +37,45 @@ protected: virtual void MessageReceived(BMessage* message); private: - const char* _ModifierKeyLabel(const key_map& map, uint32 code); - const char* _SpecialKeyLabel(const char* bytes, + enum key_kind { + kNormalKey, + kSpecialKey, + kSymbolKey + }; + + const char* _SpecialKeyLabel(const key_map& map, uint32 code); + const char* _SpecialMappedKeySymbol(const char* bytes, size_t numBytes); - bool _FunctionKeyLabel(const char* bytes, - size_t numBytes, char* text, size_t textSize); + const char* _SpecialMappedKeyLabel(const char* bytes, + size_t numBytes); + bool _FunctionKeyLabel(uint32 code, char* text, + size_t textSize); void _GetKeyLabel(Key* key, char* text, size_t textSize, - bool& specialKey); + key_kind& keyKind); bool _IsKeyPressed(int32 code); Key* _KeyForCode(int32 code); void _InvalidateKey(int32 code); void _KeyChanged(BMessage* message); + Key* _KeyAt(BPoint point); BRect _FrameFor(Key* key); float _FontSizeFor(BRect frame, const char* text); - KeyboardLayout* fLayout; - Keymap* fKeymap; + KeyboardLayout* fLayout; + Keymap* fKeymap; - uint8 fKeyState[16]; - int32 fModifiers; - int32 fDeadKey; + uint8 fKeyState[16]; + int32 fModifiers; + int32 fDeadKey; - BFont fFont; - BFont fSpecialFont; - float fFontHeight; - float fMaxFontSize; - BPoint fOffset; - float fFactor; - float fGap; + BPoint fClickPoint; + + BFont fFont; + BFont fSpecialFont; + float fFontHeight; + float fMaxFontSize; + BPoint fOffset; + float fFactor; + float fGap; }; #endif // KEYBOARD_LAYOUT_VIEW_H