* Added the ability to set a target that will receive fake B_KEY_DOWN

messages generated when pressing the keys.
* The font size is now adapted to match the key size better, maximum size is
  the current plain font.
* The keys you drag around now generate a useful B_MIME_DATA message, that other
  views can accept as well.
* Implemented support for changing the keymap via drag&drop.
* Added SetFont() method to change the font used by the keys.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29697 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2009-03-25 13:46:09 +00:00
parent d66f475749
commit 53c926befb
2 changed files with 135 additions and 44 deletions

View File

@ -42,6 +42,7 @@ void
KeyboardLayoutView::SetKeyboardLayout(KeyboardLayout* layout) KeyboardLayoutView::SetKeyboardLayout(KeyboardLayout* layout)
{ {
fLayout = layout; fLayout = layout;
_LayoutKeyboard();
Invalidate(); Invalidate();
} }
@ -54,6 +55,27 @@ KeyboardLayoutView::SetKeymap(Keymap* keymap)
} }
void
KeyboardLayoutView::SetTarget(BMessenger target)
{
fTarget = target;
}
void
KeyboardLayoutView::SetFont(const BFont& font)
{
fFont = font;
font_height fontHeight;
fFont.GetHeight(&fontHeight);
fBaseFontHeight = fontHeight.ascent + fontHeight.descent;
fBaseFontSize = fFont.Size();
Invalidate();
}
void void
KeyboardLayoutView::AttachedToWindow() KeyboardLayoutView::AttachedToWindow()
{ {
@ -62,29 +84,17 @@ KeyboardLayoutView::AttachedToWindow()
else else
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fFont = *be_plain_font; SetFont(*be_plain_font);
fSpecialFont = *be_fixed_font; fSpecialFont = *be_fixed_font;
font_height fontHeight; _LayoutKeyboard();
fFont.GetHeight(&fontHeight);
fFontHeight = fontHeight.ascent + fontHeight.descent;
FrameResized(0, 0);
} }
void void
KeyboardLayoutView::FrameResized(float width, float height) KeyboardLayoutView::FrameResized(float width, float height)
{ {
float factorX = Bounds().Width() / fLayout->Bounds().Width(); _LayoutKeyboard();
float factorY = Bounds().Height() / fLayout->Bounds().Height();
fFactor = min_c(factorX, factorY);
fOffset = BPoint((Bounds().Width() - fLayout->Bounds().Width()
* fFactor) / 2,
(Bounds().Height() - fLayout->Bounds().Height() * fFactor) / 2);
fMaxFontSize = 14;
fGap = 2;
} }
@ -133,6 +143,34 @@ KeyboardLayoutView::MouseUp(BPoint point)
if (key != NULL) { if (key != NULL) {
fKeyState[key->code / 8] &= ~(1 << (7 - (key->code & 7))); fKeyState[key->code / 8] &= ~(1 << (7 - (key->code & 7)));
_InvalidateKey(key->code); _InvalidateKey(key->code);
if (!fIsDragging && 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);
}
} }
} }
@ -189,9 +227,18 @@ KeyboardLayoutView::MouseMoved(BPoint point, uint32 transit,
bits[i + 3] = 144; bits[i + 3] = 144;
} }
BMessage drag; BMessage drag(B_MIME_DATA);
drag.AddInt32("key", key->code); drag.AddInt32("key", key->code);
char* string;
int32 numBytes;
fKeymap->GetChars(key->code, fModifiers, fDeadKey, &string,
&numBytes);
if (string != NULL) {
drag.AddData("text/plain", B_MIME_DATA, string, numBytes);
delete[] string;
}
DragMessage(&drag, bitmap, B_OP_ALPHA, offset); DragMessage(&drag, bitmap, B_OP_ALPHA, offset);
fIsDragging = true; fIsDragging = true;
@ -216,6 +263,25 @@ KeyboardLayoutView::Draw(BRect updateRect)
void void
KeyboardLayoutView::MessageReceived(BMessage* message) KeyboardLayoutView::MessageReceived(BMessage* message)
{ {
if (message->WasDropped()) {
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--;
fKeymap->SetKey(key->code, fModifiers, fDeadKey,
(const char*)data, size);
_InvalidateKey(key->code);
} else
message->PrintToStream();
}
}
switch (message->what) { switch (message->what) {
case B_UNMAPPED_KEY_DOWN: case B_UNMAPPED_KEY_DOWN:
case B_UNMAPPED_KEY_UP: case B_UNMAPPED_KEY_UP:
@ -234,6 +300,24 @@ KeyboardLayoutView::MessageReceived(BMessage* message)
} }
void
KeyboardLayoutView::_LayoutKeyboard()
{
float factorX = Bounds().Width() / fLayout->Bounds().Width();
float factorY = Bounds().Height() / fLayout->Bounds().Height();
fFactor = min_c(factorX, factorY);
fOffset = BPoint((Bounds().Width() - fLayout->Bounds().Width()
* fFactor) / 2,
(Bounds().Height() - fLayout->Bounds().Height() * fFactor) / 2);
if (fLayout->DefaultKeySize().width < 11)
fGap = 1;
else
fGap = 2;
}
void void
KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, Key* key, KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, Key* key,
BRect rect, bool pressed) BRect rect, bool pressed)
@ -254,20 +338,7 @@ KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, Key* key,
snprintf(text, sizeof(text), "%02lx", key->code); snprintf(text, sizeof(text), "%02lx", key->code);
} }
switch (keyKind) { _SetFontSize(view, keyKind);
case kNormalKey:
fFont.SetSize(_FontSizeFor(rect, text));
view->SetFont(&fFont);
break;
case kSpecialKey:
fSpecialFont.SetSize(_FontSizeFor(rect, text) * 0.7);
view->SetFont(&fSpecialFont);
break;
case kSymbolKey:
fSpecialFont.SetSize(_FontSizeFor(rect, text) * 1.6);
view->SetFont(&fSpecialFont);
break;
}
if (secondDeadKey) if (secondDeadKey)
base = kSecondDeadKeyColor; base = kSecondDeadKeyColor;
@ -568,17 +639,29 @@ KeyboardLayoutView::_FrameFor(Key* key)
} }
float void
KeyboardLayoutView::_FontSizeFor(BRect frame, const char* text) KeyboardLayoutView::_SetFontSize(BView* view, key_kind keyKind)
{ {
#if 0 BSize size = fLayout->DefaultKeySize();
//float stringWidth = fFont.StringWidth(text); float fontSize = fBaseFontSize;
// TODO: take width into account! if (fBaseFontHeight >= size.height * fFactor * 0.5) {
fontSize *= (size.height * fFactor * 0.5) / fBaseFontHeight;
if (fontSize < 8)
fontSize = 8;
}
float size = fFont.Size() * (frame.Height() - 6) / fFontHeight; switch (keyKind) {
if (size > fMaxFontSize) case kNormalKey:
return fMaxFontSize; fFont.SetSize(fontSize);
#endif view->SetFont(&fFont);
break;
return 10.0f; case kSpecialKey:
fSpecialFont.SetSize(fontSize * 0.7);
view->SetFont(&fSpecialFont);
break;
case kSymbolKey:
fSpecialFont.SetSize(fontSize * 1.6);
view->SetFont(&fSpecialFont);
break;
}
} }

View File

@ -6,6 +6,7 @@
#define KEYBOARD_LAYOUT_VIEW_H #define KEYBOARD_LAYOUT_VIEW_H
#include <Messenger.h>
#include <View.h> #include <View.h>
#include "KeyboardLayout.h" #include "KeyboardLayout.h"
@ -20,6 +21,11 @@ public:
void SetKeyboardLayout(KeyboardLayout* layout); void SetKeyboardLayout(KeyboardLayout* layout);
void SetKeymap(Keymap* keymap); void SetKeymap(Keymap* keymap);
void SetTarget(BMessenger target);
KeyboardLayout* GetKeyboardLayout() { return fLayout; }
void SetFont(const BFont& font);
protected: protected:
virtual void AttachedToWindow(); virtual void AttachedToWindow();
@ -43,6 +49,7 @@ private:
kSymbolKey kSymbolKey
}; };
void _LayoutKeyboard();
void _DrawKey(BView* view, BRect updateRect, Key* key, void _DrawKey(BView* view, BRect updateRect, Key* key,
BRect frame, bool pressed); BRect frame, bool pressed);
const char* _SpecialKeyLabel(const key_map& map, uint32 code); const char* _SpecialKeyLabel(const key_map& map, uint32 code);
@ -60,10 +67,11 @@ private:
void _KeyChanged(BMessage* message); void _KeyChanged(BMessage* message);
Key* _KeyAt(BPoint point); Key* _KeyAt(BPoint point);
BRect _FrameFor(Key* key); BRect _FrameFor(Key* key);
float _FontSizeFor(BRect frame, const char* text); void _SetFontSize(BView* view, key_kind keyKind);
KeyboardLayout* fLayout; KeyboardLayout* fLayout;
Keymap* fKeymap; Keymap* fKeymap;
BMessenger fTarget;
uint8 fKeyState[16]; uint8 fKeyState[16];
int32 fModifiers; int32 fModifiers;
@ -74,8 +82,8 @@ private:
BFont fFont; BFont fFont;
BFont fSpecialFont; BFont fSpecialFont;
float fFontHeight; float fBaseFontHeight;
float fMaxFontSize; float fBaseFontSize;
BPoint fOffset; BPoint fOffset;
float fFactor; float fFactor;
float fGap; float fGap;