From 13975ae8b8db1feddbc3e22c3cfd3d4ce06325aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 24 Mar 2009 22:09:37 +0000 Subject: [PATCH] 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 --- src/preferences/keymap/KeyboardLayoutView.cpp | 210 ++++++++++++------ src/preferences/keymap/KeyboardLayoutView.h | 3 + 2 files changed, 142 insertions(+), 71 deletions(-) diff --git a/src/preferences/keymap/KeyboardLayoutView.cpp b/src/preferences/keymap/KeyboardLayoutView.cpp index 2302e74574..e546607d60 100644 --- a/src/preferences/keymap/KeyboardLayoutView.cpp +++ b/src/preferences/keymap/KeyboardLayoutView.cpp @@ -6,17 +6,25 @@ #include "KeyboardLayoutView.h" +#include #include #include #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) { diff --git a/src/preferences/keymap/KeyboardLayoutView.h b/src/preferences/keymap/KeyboardLayoutView.h index 056cbdba1b..28ef2edb48 100644 --- a/src/preferences/keymap/KeyboardLayoutView.h +++ b/src/preferences/keymap/KeyboardLayoutView.h @@ -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;