* 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)
{
fLayout = layout;
_LayoutKeyboard();
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
KeyboardLayoutView::AttachedToWindow()
{
@ -62,29 +84,17 @@ KeyboardLayoutView::AttachedToWindow()
else
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fFont = *be_plain_font;
SetFont(*be_plain_font);
fSpecialFont = *be_fixed_font;
font_height fontHeight;
fFont.GetHeight(&fontHeight);
fFontHeight = fontHeight.ascent + fontHeight.descent;
FrameResized(0, 0);
_LayoutKeyboard();
}
void
KeyboardLayoutView::FrameResized(float width, float height)
{
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);
fMaxFontSize = 14;
fGap = 2;
_LayoutKeyboard();
}
@ -133,6 +143,34 @@ KeyboardLayoutView::MouseUp(BPoint point)
if (key != NULL) {
fKeyState[key->code / 8] &= ~(1 << (7 - (key->code & 7)));
_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;
}
BMessage drag;
BMessage drag(B_MIME_DATA);
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);
fIsDragging = true;
@ -216,6 +263,25 @@ KeyboardLayoutView::Draw(BRect updateRect)
void
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) {
case B_UNMAPPED_KEY_DOWN:
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
KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, Key* key,
BRect rect, bool pressed)
@ -254,20 +338,7 @@ KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, Key* key,
snprintf(text, sizeof(text), "%02lx", key->code);
}
switch (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;
}
_SetFontSize(view, keyKind);
if (secondDeadKey)
base = kSecondDeadKeyColor;
@ -568,17 +639,29 @@ KeyboardLayoutView::_FrameFor(Key* key)
}
float
KeyboardLayoutView::_FontSizeFor(BRect frame, const char* text)
void
KeyboardLayoutView::_SetFontSize(BView* view, key_kind keyKind)
{
#if 0
//float stringWidth = fFont.StringWidth(text);
// TODO: take width into account!
BSize size = fLayout->DefaultKeySize();
float fontSize = fBaseFontSize;
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;
if (size > fMaxFontSize)
return fMaxFontSize;
#endif
return 10.0f;
switch (keyKind) {
case kNormalKey:
fFont.SetSize(fontSize);
view->SetFont(&fFont);
break;
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
#include <Messenger.h>
#include <View.h>
#include "KeyboardLayout.h"
@ -20,6 +21,11 @@ public:
void SetKeyboardLayout(KeyboardLayout* layout);
void SetKeymap(Keymap* keymap);
void SetTarget(BMessenger target);
KeyboardLayout* GetKeyboardLayout() { return fLayout; }
void SetFont(const BFont& font);
protected:
virtual void AttachedToWindow();
@ -43,6 +49,7 @@ private:
kSymbolKey
};
void _LayoutKeyboard();
void _DrawKey(BView* view, BRect updateRect, Key* key,
BRect frame, bool pressed);
const char* _SpecialKeyLabel(const key_map& map, uint32 code);
@ -60,10 +67,11 @@ private:
void _KeyChanged(BMessage* message);
Key* _KeyAt(BPoint point);
BRect _FrameFor(Key* key);
float _FontSizeFor(BRect frame, const char* text);
void _SetFontSize(BView* view, key_kind keyKind);
KeyboardLayout* fLayout;
Keymap* fKeymap;
BMessenger fTarget;
uint8 fKeyState[16];
int32 fModifiers;
@ -74,8 +82,8 @@ private:
BFont fFont;
BFont fSpecialFont;
float fFontHeight;
float fMaxFontSize;
float fBaseFontHeight;
float fBaseFontSize;
BPoint fOffset;
float fFactor;
float fGap;