Another work-in-progress commit:

* Started working on dragging keys around.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29683 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2009-03-24 22:09:37 +00:00
parent 52e3ce2c74
commit 13975ae8b8
2 changed files with 142 additions and 71 deletions

View File

@ -6,17 +6,25 @@
#include "KeyboardLayoutView.h"
#include <Bitmap.h>
#include <ControlLook.h>
#include <Window.h>
#include "Keymap.h"
static const rgb_color kBrightColor = {230, 230, 230, 255};
static const rgb_color kDarkColor = {200, 200, 200, 255};
static const rgb_color kSecondDeadKeyColor = {240, 240, 150, 255};
static const rgb_color kDeadKeyColor = {152, 203, 255, 255};
KeyboardLayoutView::KeyboardLayoutView(const char* name)
: BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
fKeymap(NULL),
fModifiers(0),
fDeadKey(0)
fDeadKey(0),
fIsDragging(false)
{
fLayout = new KeyboardLayout;
memset(fKeyState, 0, sizeof(fKeyState));
@ -108,6 +116,7 @@ void
KeyboardLayoutView::MouseDown(BPoint point)
{
fClickPoint = point;
fIsDragging = false;
Key* key = _KeyAt(point);
if (key != NULL) {
@ -132,85 +141,74 @@ void
KeyboardLayoutView::MouseMoved(BPoint point, uint32 transit,
const BMessage* dragMessage)
{
if (fKeymap == NULL)
return;
if (dragMessage != NULL) {
#if 0
// TODO: check if we support this message!
Key* key = _KeyAt(point);
if (key == NULL)
return;
// TODO: have a mouse key state, and a current drag key!
memset(fKeyState, 0, sizeof(fKeyState));
fKeyState[key->code / 8] = (1 << (7 - (key->code & 7)));
_InvalidateKey(key->code);
#endif
} else if (!fIsDragging && (fabs(point.x - fClickPoint.x) > 4
|| fabs(point.y - fClickPoint.y) > 4)) {
// start dragging
Key* key = _KeyAt(fClickPoint);
if (key == NULL)
return;
BRect frame = _FrameFor(key);
BPoint offset = fClickPoint - frame.LeftTop();
frame.OffsetTo(B_ORIGIN);
BRect rect = frame;
rect.right--;
rect.bottom--;
BBitmap* bitmap = new BBitmap(rect, B_BITMAP_ACCEPTS_VIEWS, B_RGBA32);
bitmap->Lock();
BView* view = new BView(rect, "drag", 0, 0);
bitmap->AddChild(view);
_DrawKey(view, frame, key, frame, false);
view->Sync();
bitmap->RemoveChild(view);
bitmap->Unlock();
// Make it transparent
// TODO: is there a better way to do this?
uint8* bits = (uint8*)bitmap->Bits();
for (int32 i = 0; i < bitmap->BitsLength(); i += 4) {
bits[i + 3] = 144;
}
BMessage drag;
drag.AddInt32("key", key->code);
DragMessage(&drag, bitmap, B_OP_ALPHA, offset);
fIsDragging = true;
fKeyState[key->code / 8] &= ~(1 << (7 - (key->code & 7)));
_InvalidateKey(key->code);
}
}
void
KeyboardLayoutView::Draw(BRect updateRect)
{
static const rgb_color kBrightColor = {230, 230, 230};
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++) {
Key* key = fLayout->KeyAt(i);
BRect rect = _FrameFor(key);
rgb_color base = key->dark ? kDarkColor : kBrightColor;
bool pressed = _IsKeyPressed(key->code);
key_kind keyKind = kNormalKey;
int32 deadKey = 0;
bool secondDeadKey;
char text[32];
if (fKeymap != NULL) {
_GetKeyLabel(key, text, sizeof(text), keyKind);
deadKey = fKeymap->IsDeadKey(key->code, fModifiers);
secondDeadKey = fKeymap->IsDeadSecondKey(key->code, fModifiers,
fDeadKey);
} else {
// Show the key code if there is no keymap
snprintf(text, sizeof(text), "%02lx", key->code);
}
switch (keyKind) {
case kNormalKey:
fFont.SetSize(_FontSizeFor(rect, text));
SetFont(&fFont);
break;
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) {
be_control_look->DrawButtonFrame(this, rect, updateRect, base,
pressed ? BControlLook::B_ACTIVATED : 0);
be_control_look->DrawButtonBackground(this, rect, updateRect,
base, pressed ? BControlLook::B_ACTIVATED : 0);
// TODO: make font size depend on key size!
rect.InsetBy(1, 1);
be_control_look->DrawLabel(this, text, rect, updateRect,
base, 0, BAlignment(B_ALIGN_CENTER, B_ALIGN_MIDDLE));
} else if (key->shape == kEnterKeyShape) {
// TODO: make better!
rect.bottom -= 20;
be_control_look->DrawButtonBackground(this, rect, updateRect,
base, 0, BControlLook::B_LEFT_BORDER
| BControlLook::B_RIGHT_BORDER
| BControlLook::B_TOP_BORDER);
rect = _FrameFor(key);
rect.top += 20;
rect.left += 10;
be_control_look->DrawButtonBackground(this, rect, updateRect,
base, 0, BControlLook::B_LEFT_BORDER
| BControlLook::B_RIGHT_BORDER
| BControlLook::B_BOTTOM_BORDER);
}
_DrawKey(this, updateRect, key, _FrameFor(key),
_IsKeyPressed(key->code));
}
}
@ -236,6 +234,76 @@ KeyboardLayoutView::MessageReceived(BMessage* message)
}
void
KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, Key* key,
BRect rect, bool pressed)
{
rgb_color base = key->dark ? kDarkColor : kBrightColor;
key_kind keyKind = kNormalKey;
int32 deadKey = 0;
bool secondDeadKey;
char text[32];
if (fKeymap != NULL) {
_GetKeyLabel(key, text, sizeof(text), keyKind);
deadKey = fKeymap->IsDeadKey(key->code, fModifiers);
secondDeadKey = fKeymap->IsDeadSecondKey(key->code, fModifiers,
fDeadKey);
} else {
// Show the key code if there is no keymap
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;
}
if (secondDeadKey)
base = kSecondDeadKeyColor;
else if (deadKey > 0)
base = kDeadKeyColor;
if (key->shape == kRectangleKeyShape) {
be_control_look->DrawButtonFrame(view, rect, updateRect, base,
pressed ? BControlLook::B_ACTIVATED : 0);
be_control_look->DrawButtonBackground(view, rect, updateRect,
base, pressed ? BControlLook::B_ACTIVATED : 0);
// TODO: make font size depend on key size!
rect.InsetBy(1, 1);
be_control_look->DrawLabel(view, text, rect, updateRect,
base, 0, BAlignment(B_ALIGN_CENTER, B_ALIGN_MIDDLE));
} else if (key->shape == kEnterKeyShape) {
// TODO: make better!
rect.bottom -= 20;
be_control_look->DrawButtonBackground(view, rect, updateRect,
base, 0, BControlLook::B_LEFT_BORDER
| BControlLook::B_RIGHT_BORDER
| BControlLook::B_TOP_BORDER);
rect = _FrameFor(key);
rect.top += 20;
rect.left += 10;
be_control_look->DrawButtonBackground(view, rect, updateRect,
base, 0, BControlLook::B_LEFT_BORDER
| BControlLook::B_RIGHT_BORDER
| BControlLook::B_BOTTOM_BORDER);
}
}
const char*
KeyboardLayoutView::_SpecialKeyLabel(const key_map& map, uint32 code)
{

View File

@ -43,6 +43,8 @@ private:
kSymbolKey
};
void _DrawKey(BView* view, BRect updateRect, Key* key,
BRect frame, bool pressed);
const char* _SpecialKeyLabel(const key_map& map, uint32 code);
const char* _SpecialMappedKeySymbol(const char* bytes,
size_t numBytes);
@ -68,6 +70,7 @@ private:
int32 fDeadKey;
BPoint fClickPoint;
bool fIsDragging;
BFont fFont;
BFont fSpecialFont;