* 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
This commit is contained in:
Axel Dörfler
2009-03-24 09:45:32 +00:00
parent 193882e035
commit 8ba65ba1b4
2 changed files with 176 additions and 68 deletions
+148 -51
View File
@@ -107,12 +107,24 @@ KeyboardLayoutView::KeyUp(const char* bytes, int32 numBytes)
void void
KeyboardLayoutView::MouseDown(BPoint point) 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 void
KeyboardLayoutView::MouseUp(BPoint point) 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 void
KeyboardLayoutView::Draw(BRect updateRect) KeyboardLayoutView::Draw(BRect updateRect)
{ {
rgb_color brightColor = {230, 230, 230}; static const rgb_color kBrightColor = {230, 230, 230};
rgb_color darkColor = {200, 200, 200}; 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++) { for (int32 i = 0; i < fLayout->CountKeys(); i++) {
Key* key = fLayout->KeyAt(i); Key* key = fLayout->KeyAt(i);
BRect rect = _FrameFor(key); BRect rect = _FrameFor(key);
rgb_color base = key->dark ? darkColor : brightColor; rgb_color base = key->dark ? kDarkColor : kBrightColor;
bool pressed = _IsKeyPressed(key->code); bool pressed = _IsKeyPressed(key->code);
bool special = false; key_kind keyKind = kNormalKey;
int32 deadKey = 0;
bool secondDeadKey;
char text[32]; char text[32];
if (fKeymap != NULL) { 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 { } else {
// Show the key code if there is no keymap // Show the key code if there is no keymap
snprintf(text, sizeof(text), "%02lx", key->code); snprintf(text, sizeof(text), "%02lx", key->code);
} }
if (special) { switch (keyKind) {
fSpecialFont.SetSize(_FontSizeFor(rect, text) * 0.8); case kNormalKey:
SetFont(&fSpecialFont); fFont.SetSize(_FontSizeFor(rect, text));
} else { SetFont(&fFont);
fFont.SetSize(_FontSizeFor(rect, text)); break;
SetFont(&fFont); 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) { if (key->shape == kRectangleKeyShape) {
be_control_look->DrawButtonFrame(this, rect, updateRect, base, be_control_look->DrawButtonFrame(this, rect, updateRect, base,
pressed ? BControlLook::B_ACTIVATED : 0); pressed ? BControlLook::B_ACTIVATED : 0);
@@ -168,16 +199,16 @@ KeyboardLayoutView::Draw(BRect updateRect)
// TODO: make better! // TODO: make better!
rect.bottom -= 20; rect.bottom -= 20;
be_control_look->DrawButtonBackground(this, rect, updateRect, be_control_look->DrawButtonBackground(this, rect, updateRect,
key->dark ? darkColor : brightColor, 0, base, 0, BControlLook::B_LEFT_BORDER
BControlLook::B_LEFT_BORDER | BControlLook::B_RIGHT_BORDER | BControlLook::B_RIGHT_BORDER
| BControlLook::B_TOP_BORDER); | BControlLook::B_TOP_BORDER);
rect = _FrameFor(key); rect = _FrameFor(key);
rect.top += 20; rect.top += 20;
rect.left += 10; rect.left += 10;
be_control_look->DrawButtonBackground(this, rect, updateRect, be_control_look->DrawButtonBackground(this, rect, updateRect,
key->dark ? darkColor : brightColor, 0, base, 0, BControlLook::B_LEFT_BORDER
BControlLook::B_LEFT_BORDER | BControlLook::B_RIGHT_BORDER | BControlLook::B_RIGHT_BORDER
| BControlLook::B_BOTTOM_BORDER); | BControlLook::B_BOTTOM_BORDER);
} }
} }
@@ -206,7 +237,7 @@ KeyboardLayoutView::MessageReceived(BMessage* message)
const char* const char*
KeyboardLayoutView::_ModifierKeyLabel(const key_map& map, uint32 code) KeyboardLayoutView::_SpecialKeyLabel(const key_map& map, uint32 code)
{ {
if (code == map.caps_key) if (code == map.caps_key)
return "CAPS LOCK"; return "CAPS LOCK";
@@ -224,19 +255,21 @@ KeyboardLayoutView::_ModifierKeyLabel(const key_map& map, uint32 code)
return "OPTION"; return "OPTION";
if (code == map.menu_key) if (code == map.menu_key)
return "MENU"; return "MENU";
if (code == B_PRINT_KEY)
return "PRINT";
if (code == B_PAUSE_KEY)
return "PAUSE";
return NULL; return NULL;
} }
const char* const char*
KeyboardLayoutView::_SpecialKeyLabel(const char* bytes, size_t numBytes) KeyboardLayoutView::_SpecialMappedKeySymbol(const char* bytes, size_t numBytes)
{ {
if (numBytes != 1) if (numBytes != 1)
return NULL; return NULL;
if (bytes[0] == B_ESCAPE)
return "ESC";
if (bytes[0] == B_TAB) if (bytes[0] == B_TAB)
return "\xe2\x86\xb9"; return "\xe2\x86\xb9";
if (bytes[0] == B_ENTER) if (bytes[0] == B_ENTER)
@@ -244,19 +277,6 @@ KeyboardLayoutView::_SpecialKeyLabel(const char* bytes, size_t numBytes)
if (bytes[0] == B_BACKSPACE) if (bytes[0] == B_BACKSPACE)
return "back";//\xe2\x86\x92"; 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) if (bytes[0] == B_UP_ARROW)
return "\xe2\x86\x91"; return "\xe2\x86\x91";
if (bytes[0] == B_LEFT_ARROW) if (bytes[0] == B_LEFT_ARROW)
@@ -270,15 +290,39 @@ KeyboardLayoutView::_SpecialKeyLabel(const char* bytes, size_t numBytes)
} }
bool const char*
KeyboardLayoutView::_FunctionKeyLabel(const char* bytes, size_t numBytes, KeyboardLayoutView::_SpecialMappedKeyLabel(const char* bytes, size_t numBytes)
char* text, size_t textSize)
{ {
if (bytes[0] != B_FUNCTION_KEY) if (numBytes != 1)
return false; return NULL;
if (bytes[1] >= B_F1_KEY && bytes[1] <= B_F12_KEY) { if (bytes[0] == B_ESCAPE)
snprintf(text, textSize, "F%d", bytes[1] + 1 - B_F1_KEY); 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; return true;
} }
@@ -288,16 +332,21 @@ KeyboardLayoutView::_FunctionKeyLabel(const char* bytes, size_t numBytes,
void void
KeyboardLayoutView::_GetKeyLabel(Key* key, char* text, size_t textSize, KeyboardLayoutView::_GetKeyLabel(Key* key, char* text, size_t textSize,
bool& specialKey) key_kind& keyKind)
{ {
const key_map& map = fKeymap->Map(); const key_map& map = fKeymap->Map();
specialKey = false; keyKind = kNormalKey;
text[0] = '\0'; text[0] = '\0';
const char* modifier = _ModifierKeyLabel(map, key->code); const char* special = _SpecialKeyLabel(map, key->code);
if (modifier != NULL) { if (special != NULL) {
strlcpy(text, modifier, textSize); strlcpy(text, special, textSize);
specialKey = true; keyKind = kSpecialKey;
return;
}
if (_FunctionKeyLabel(key->code, text, textSize)) {
keyKind = kSpecialKey;
return; return;
} }
@@ -306,14 +355,17 @@ KeyboardLayoutView::_GetKeyLabel(Key* key, char* text, size_t textSize,
fKeymap->GetChars(key->code, fModifiers, fDeadKey, &bytes, fKeymap->GetChars(key->code, fModifiers, fDeadKey, &bytes,
&numBytes); &numBytes);
if (bytes != NULL) { if (bytes != NULL) {
const char* special = _SpecialKeyLabel(bytes, numBytes); special = _SpecialMappedKeyLabel(bytes, numBytes);
if (special != NULL) { if (special != NULL) {
strlcpy(text, special, textSize); strlcpy(text, special, textSize);
specialKey = true; keyKind = kSpecialKey;
return; return;
} }
if (_FunctionKeyLabel(bytes, numBytes, text, textSize)) {
specialKey = true; special = _SpecialMappedKeySymbol(bytes, numBytes);
if (special != NULL) {
strlcpy(text, special, textSize);
keyKind = kSymbolKey;
return; return;
} }
@@ -341,7 +393,7 @@ Key*
KeyboardLayoutView::_KeyForCode(int32 code) KeyboardLayoutView::_KeyForCode(int32 code)
{ {
// TODO: have a lookup array // TODO: have a lookup array
for (int32 i = 0; i < fLayout->CountKeys(); i++) { for (int32 i = 0; i < fLayout->CountKeys(); i++) {
Key* key = fLayout->KeyAt(i); Key* key = fLayout->KeyAt(i);
if (key->code == code) if (key->code == code)
@@ -366,17 +418,37 @@ KeyboardLayoutView::_KeyChanged(BMessage* message)
{ {
const uint8* state; const uint8* state;
ssize_t size; ssize_t size;
int32 key;
if (message->FindData("states", B_UINT8_TYPE, (const void**)&state, &size) if (message->FindData("states", B_UINT8_TYPE, (const void**)&state, &size)
!= B_OK) != B_OK
|| message->FindInt32("key", &key) != B_OK)
return; return;
// Update key state, and invalidate change keys // 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++) { for (int32 i = 0; i < 16; i++) {
if (fKeyState[i] != state[i]) { if (fKeyState[i] != state[i]) {
uint8 diff = fKeyState[i] ^ state[i]; uint8 diff = fKeyState[i] ^ state[i];
fKeyState[i] = state[i]; fKeyState[i] = state[i];
if (!checkSingle)
continue;
for (int32 j = 7; diff != 0; j--, diff >>= 1) { for (int32 j = 7; diff != 0; j--, diff >>= 1) {
if (diff & 1) { if (diff & 1) {
_InvalidateKey(i * 8 + j); _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 BRect
KeyboardLayoutView::_FrameFor(Key* key) KeyboardLayoutView::_FrameFor(Key* key)
{ {
+28 -17
View File
@@ -37,34 +37,45 @@ protected:
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
private: private:
const char* _ModifierKeyLabel(const key_map& map, uint32 code); enum key_kind {
const char* _SpecialKeyLabel(const char* bytes, kNormalKey,
kSpecialKey,
kSymbolKey
};
const char* _SpecialKeyLabel(const key_map& map, uint32 code);
const char* _SpecialMappedKeySymbol(const char* bytes,
size_t numBytes); size_t numBytes);
bool _FunctionKeyLabel(const char* bytes, const char* _SpecialMappedKeyLabel(const char* bytes,
size_t numBytes, char* text, size_t textSize); size_t numBytes);
bool _FunctionKeyLabel(uint32 code, char* text,
size_t textSize);
void _GetKeyLabel(Key* key, char* text, size_t textSize, void _GetKeyLabel(Key* key, char* text, size_t textSize,
bool& specialKey); 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 _KeyChanged(BMessage* message); void _KeyChanged(BMessage* message);
Key* _KeyAt(BPoint point);
BRect _FrameFor(Key* key); BRect _FrameFor(Key* key);
float _FontSizeFor(BRect frame, const char* text); float _FontSizeFor(BRect frame, const char* text);
KeyboardLayout* fLayout; KeyboardLayout* fLayout;
Keymap* fKeymap; Keymap* fKeymap;
uint8 fKeyState[16]; uint8 fKeyState[16];
int32 fModifiers; int32 fModifiers;
int32 fDeadKey; int32 fDeadKey;
BFont fFont; BPoint fClickPoint;
BFont fSpecialFont;
float fFontHeight; BFont fFont;
float fMaxFontSize; BFont fSpecialFont;
BPoint fOffset; float fFontHeight;
float fFactor; float fMaxFontSize;
float fGap; BPoint fOffset;
float fFactor;
float fGap;
}; };
#endif // KEYBOARD_LAYOUT_VIEW_H #endif // KEYBOARD_LAYOUT_VIEW_H