* 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:
parent
d66f475749
commit
53c926befb
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user