* 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:
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user