* Now uses an offscreen bitmap for flicker free drawing.
* Only trigger a redraw on B_MODIFIER_CHANGED if something actually changed. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29747 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -24,6 +24,7 @@ static const rgb_color kLitIndicatorColor = {116, 212, 83, 255};
|
|||||||
|
|
||||||
KeyboardLayoutView::KeyboardLayoutView(const char* name)
|
KeyboardLayoutView::KeyboardLayoutView(const char* name)
|
||||||
: BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
|
: BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
|
||||||
|
fOffscreenBitmap(NULL),
|
||||||
fKeymap(NULL),
|
fKeymap(NULL),
|
||||||
fModifiers(0),
|
fModifiers(0),
|
||||||
fDeadKey(0),
|
fDeadKey(0),
|
||||||
@@ -39,6 +40,7 @@ KeyboardLayoutView::KeyboardLayoutView(const char* name)
|
|||||||
|
|
||||||
KeyboardLayoutView::~KeyboardLayoutView()
|
KeyboardLayoutView::~KeyboardLayoutView()
|
||||||
{
|
{
|
||||||
|
delete fOffscreenBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -83,15 +85,13 @@ KeyboardLayoutView::SetFont(const BFont& font)
|
|||||||
void
|
void
|
||||||
KeyboardLayoutView::AttachedToWindow()
|
KeyboardLayoutView::AttachedToWindow()
|
||||||
{
|
{
|
||||||
if (Parent())
|
SetViewColor(B_TRANSPARENT_COLOR);
|
||||||
SetViewColor(Parent()->ViewColor());
|
|
||||||
else
|
|
||||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
|
||||||
|
|
||||||
SetFont(*be_plain_font);
|
SetFont(*be_plain_font);
|
||||||
fSpecialFont = *be_fixed_font;
|
fSpecialFont = *be_fixed_font;
|
||||||
fModifiers = modifiers();
|
fModifiers = modifiers();
|
||||||
|
|
||||||
|
_InitOffscreen();
|
||||||
_LayoutKeyboard();
|
_LayoutKeyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,6 +99,7 @@ KeyboardLayoutView::AttachedToWindow()
|
|||||||
void
|
void
|
||||||
KeyboardLayoutView::FrameResized(float width, float height)
|
KeyboardLayoutView::FrameResized(float width, float height)
|
||||||
{
|
{
|
||||||
|
_InitOffscreen();
|
||||||
_LayoutKeyboard();
|
_LayoutKeyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,12 +230,28 @@ KeyboardLayoutView::MouseMoved(BPoint point, uint32 transit,
|
|||||||
void
|
void
|
||||||
KeyboardLayoutView::Draw(BRect updateRect)
|
KeyboardLayoutView::Draw(BRect updateRect)
|
||||||
{
|
{
|
||||||
|
BView* view;
|
||||||
|
if (fOffscreenBitmap != NULL) {
|
||||||
|
view = fOffscreenView;
|
||||||
|
view->LockLooper();
|
||||||
|
} else
|
||||||
|
view = this;
|
||||||
|
|
||||||
|
// Draw background
|
||||||
|
|
||||||
|
if (Parent())
|
||||||
|
view->SetLowColor(Parent()->ViewColor());
|
||||||
|
else
|
||||||
|
view->SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
|
||||||
|
view->FillRect(updateRect, B_SOLID_LOW);
|
||||||
|
|
||||||
// Draw keys
|
// Draw keys
|
||||||
|
|
||||||
for (int32 i = 0; i < fLayout->CountKeys(); i++) {
|
for (int32 i = 0; i < fLayout->CountKeys(); i++) {
|
||||||
Key* key = fLayout->KeyAt(i);
|
Key* key = fLayout->KeyAt(i);
|
||||||
|
|
||||||
_DrawKey(this, updateRect, key, _FrameFor(key),
|
_DrawKey(view, updateRect, key, _FrameFor(key),
|
||||||
_IsKeyPressed(key->code));
|
_IsKeyPressed(key->code));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,49 +260,15 @@ KeyboardLayoutView::Draw(BRect updateRect)
|
|||||||
for (int32 i = 0; i < fLayout->CountIndicators(); i++) {
|
for (int32 i = 0; i < fLayout->CountIndicators(); i++) {
|
||||||
Indicator* indicator = fLayout->IndicatorAt(i);
|
Indicator* indicator = fLayout->IndicatorAt(i);
|
||||||
|
|
||||||
BRect rect = _FrameFor(indicator->frame);
|
_DrawIndicator(view, updateRect, indicator, _FrameFor(indicator->frame),
|
||||||
float rectTop = rect.top;
|
(fModifiers & indicator->modifier) != 0);
|
||||||
rect.top += 2 * rect.Height() / 3;
|
}
|
||||||
|
|
||||||
const char* label = NULL;
|
if (fOffscreenBitmap != NULL) {
|
||||||
if (indicator->modifier == B_CAPS_LOCK)
|
view->Sync();
|
||||||
label = "caps";
|
view->UnlockLooper();
|
||||||
else if (indicator->modifier == B_NUM_LOCK)
|
|
||||||
label = "num";
|
|
||||||
else if (indicator->modifier == B_SCROLL_LOCK)
|
|
||||||
label = "scroll";
|
|
||||||
if (label != NULL) {
|
|
||||||
_SetFontSize(this, kIndicator);
|
|
||||||
|
|
||||||
font_height fontHeight;
|
DrawBitmapAsync(fOffscreenBitmap, BPoint(0, 0));
|
||||||
GetFontHeight(&fontHeight);
|
|
||||||
if (ceilf(rect.top - fontHeight.ascent + fontHeight.descent - 2)
|
|
||||||
>= rectTop) {
|
|
||||||
SetHighColor(0, 0, 0);
|
|
||||||
SetLowColor(ViewColor());
|
|
||||||
|
|
||||||
BString text(label);
|
|
||||||
TruncateString(&text, B_TRUNCATE_END, rect.Width());
|
|
||||||
DrawString(text.String(), BPoint(ceilf(rect.left + (rect.Width()
|
|
||||||
- StringWidth(text.String())) / 2),
|
|
||||||
ceilf(rect.top - fontHeight.descent - 2)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rect.left += rect.Width() / 4;
|
|
||||||
rect.right -= rect.Width() / 3;
|
|
||||||
|
|
||||||
rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
|
|
||||||
rgb_color base;
|
|
||||||
if ((fModifiers & indicator->modifier) != 0)
|
|
||||||
base = kLitIndicatorColor;
|
|
||||||
else
|
|
||||||
base = kDarkColor;
|
|
||||||
|
|
||||||
be_control_look->DrawButtonFrame(this, rect, updateRect, base,
|
|
||||||
background, BControlLook::B_DISABLED);
|
|
||||||
be_control_look->DrawButtonBackground(this, rect, updateRect,
|
|
||||||
base, BControlLook::B_DISABLED);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,11 +329,16 @@ KeyboardLayoutView::MessageReceived(BMessage* message)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case B_MODIFIERS_CHANGED:
|
case B_MODIFIERS_CHANGED:
|
||||||
if (message->FindInt32("modifiers", &fModifiers) == B_OK) {
|
{
|
||||||
|
int32 newModifiers;
|
||||||
|
if (message->FindInt32("modifiers", &newModifiers) == B_OK
|
||||||
|
&& fModifiers != newModifiers) {
|
||||||
|
fModifiers = newModifiers;
|
||||||
_EvaluateDropTarget(fDropPoint);
|
_EvaluateDropTarget(fDropPoint);
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BView::MessageReceived(message);
|
BView::MessageReceived(message);
|
||||||
@@ -359,6 +347,40 @@ KeyboardLayoutView::MessageReceived(BMessage* message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
KeyboardLayoutView::_InitOffscreen()
|
||||||
|
{
|
||||||
|
delete fOffscreenBitmap;
|
||||||
|
fOffscreenView = NULL;
|
||||||
|
|
||||||
|
fOffscreenBitmap = new(std::nothrow) BBitmap(Bounds(),
|
||||||
|
B_BITMAP_ACCEPTS_VIEWS, B_RGB32);
|
||||||
|
if (fOffscreenBitmap != NULL && fOffscreenBitmap->IsValid()) {
|
||||||
|
fOffscreenBitmap->Lock();
|
||||||
|
fOffscreenView = new(std::nothrow) BView(Bounds(), "offscreen view",
|
||||||
|
0, 0);
|
||||||
|
if (fOffscreenView != NULL) {
|
||||||
|
if (Parent() != NULL) {
|
||||||
|
fOffscreenView->SetViewColor(Parent()->ViewColor());
|
||||||
|
} else {
|
||||||
|
fOffscreenView->SetViewColor(
|
||||||
|
ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
}
|
||||||
|
|
||||||
|
fOffscreenView->SetLowColor(fOffscreenView->ViewColor());
|
||||||
|
fOffscreenBitmap->AddChild(fOffscreenView);
|
||||||
|
}
|
||||||
|
fOffscreenBitmap->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fOffscreenView == NULL) {
|
||||||
|
// something went wrong
|
||||||
|
delete fOffscreenBitmap;
|
||||||
|
fOffscreenBitmap = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
KeyboardLayoutView::_LayoutKeyboard()
|
KeyboardLayoutView::_LayoutKeyboard()
|
||||||
{
|
{
|
||||||
@@ -467,6 +489,52 @@ KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, const Key* key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
KeyboardLayoutView::_DrawIndicator(BView* view, BRect updateRect,
|
||||||
|
const Indicator* indicator, BRect rect, bool lit)
|
||||||
|
{
|
||||||
|
float rectTop = rect.top;
|
||||||
|
rect.top += 2 * rect.Height() / 3;
|
||||||
|
|
||||||
|
const char* label = NULL;
|
||||||
|
if (indicator->modifier == B_CAPS_LOCK)
|
||||||
|
label = "caps";
|
||||||
|
else if (indicator->modifier == B_NUM_LOCK)
|
||||||
|
label = "num";
|
||||||
|
else if (indicator->modifier == B_SCROLL_LOCK)
|
||||||
|
label = "scroll";
|
||||||
|
if (label != NULL) {
|
||||||
|
_SetFontSize(view, kIndicator);
|
||||||
|
|
||||||
|
font_height fontHeight;
|
||||||
|
GetFontHeight(&fontHeight);
|
||||||
|
if (ceilf(rect.top - fontHeight.ascent + fontHeight.descent - 2)
|
||||||
|
>= rectTop) {
|
||||||
|
view->SetHighColor(0, 0, 0);
|
||||||
|
view->SetLowColor(ViewColor());
|
||||||
|
|
||||||
|
BString text(label);
|
||||||
|
view->TruncateString(&text, B_TRUNCATE_END, rect.Width());
|
||||||
|
view->DrawString(text.String(),
|
||||||
|
BPoint(ceilf(rect.left + (rect.Width()
|
||||||
|
- StringWidth(text.String())) / 2),
|
||||||
|
ceilf(rect.top - fontHeight.descent - 2)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.left += rect.Width() / 4;
|
||||||
|
rect.right -= rect.Width() / 3;
|
||||||
|
|
||||||
|
rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
|
||||||
|
rgb_color base = lit ? kLitIndicatorColor : kDarkColor;
|
||||||
|
|
||||||
|
be_control_look->DrawButtonFrame(view, rect, updateRect, base,
|
||||||
|
background, BControlLook::B_DISABLED);
|
||||||
|
be_control_look->DrawButtonBackground(view, rect, updateRect,
|
||||||
|
base, BControlLook::B_DISABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
KeyboardLayoutView::_SpecialKeyLabel(const key_map& map, uint32 code)
|
KeyboardLayoutView::_SpecialKeyLabel(const key_map& map, uint32 code)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,12 +50,16 @@ private:
|
|||||||
kIndicator
|
kIndicator
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void _InitOffscreen();
|
||||||
void _LayoutKeyboard();
|
void _LayoutKeyboard();
|
||||||
void _DrawKeyButton(BView* view, BRect& rect,
|
void _DrawKeyButton(BView* view, BRect& rect,
|
||||||
BRect updateRect, rgb_color base,
|
BRect updateRect, rgb_color base,
|
||||||
rgb_color background, bool pressed);
|
rgb_color background, bool pressed);
|
||||||
void _DrawKey(BView* view, BRect updateRect,
|
void _DrawKey(BView* view, BRect updateRect,
|
||||||
const Key* key, BRect frame, bool pressed);
|
const Key* key, BRect frame, bool pressed);
|
||||||
|
void _DrawIndicator(BView* view, BRect updateRect,
|
||||||
|
const Indicator* indicator, BRect rect,
|
||||||
|
bool lit);
|
||||||
const char* _SpecialKeyLabel(const key_map& map, uint32 code);
|
const char* _SpecialKeyLabel(const key_map& map, uint32 code);
|
||||||
const char* _SpecialMappedKeySymbol(const char* bytes,
|
const char* _SpecialMappedKeySymbol(const char* bytes,
|
||||||
size_t numBytes);
|
size_t numBytes);
|
||||||
@@ -78,6 +82,9 @@ private:
|
|||||||
void _EvaluateDropTarget(BPoint point);
|
void _EvaluateDropTarget(BPoint point);
|
||||||
void _SendFakeKeyDown(const Key* key);
|
void _SendFakeKeyDown(const Key* key);
|
||||||
|
|
||||||
|
BBitmap* fOffscreenBitmap;
|
||||||
|
BView* fOffscreenView;
|
||||||
|
|
||||||
KeyboardLayout* fLayout;
|
KeyboardLayout* fLayout;
|
||||||
Keymap* fKeymap;
|
Keymap* fKeymap;
|
||||||
BMessenger fTarget;
|
BMessenger fTarget;
|
||||||
|
|||||||
Reference in New Issue
Block a user