142176b84SAxel Dörfler/*
2b19e758bSAxel Dörfler * Copyright 2009-2010, Axel D��rfler, axeld@pinc-software.de.
3a073305cSJohn Scipione * Copyright 2013-2014 Haiku, Inc. All rights reserved.
442176b84SAxel Dörfler * Distributed under the terms of the MIT License.
5a073305cSJohn Scipione *
6a073305cSJohn Scipione * Authors:
7a073305cSJohn Scipione *		Axel D��rfler, axeld@pinc-software.de
8a073305cSJohn Scipione *		John Scipione, jscipione@gmail.com
942176b84SAxel Dörfler */
1042176b84SAxel Dörfler
1142176b84SAxel Dörfler
1242176b84SAxel Dörfler#include "KeyboardLayoutView.h"
1342176b84SAxel Dörfler
141e855c37SIngo Weinhold#include <stdio.h>
151e855c37SIngo Weinhold#include <stdlib.h>
161e855c37SIngo Weinhold
177e5ffaa2SAxel Dörfler#include <Beep.h>
1813975ae8SAxel Dörfler#include <Bitmap.h>
1942176b84SAxel Dörfler#include <ControlLook.h>
20be09c2a1SAxel Dörfler#include <LayoutUtils.h>
21173b5a68SJohn Scipione#include <MenuItem.h>
22173b5a68SJohn Scipione#include <PopUpMenu.h>
23a869d32eSAxel Dörfler#include <Region.h>
2442176b84SAxel Dörfler#include <Window.h>
2542176b84SAxel Dörfler
2642176b84SAxel Dörfler#include "Keymap.h"
27173b5a68SJohn Scipione#include "KeymapApplication.h"
28173b5a68SJohn Scipione
29173b5a68SJohn Scipione
30173b5a68SJohn Scipione#undef B_TRANSLATION_CONTEXT
31173b5a68SJohn Scipione#define B_TRANSLATION_CONTEXT "Keyboard Layout View"
3242176b84SAxel Dörfler
3342176b84SAxel Dörfler
3413975ae8SAxel Dörflerstatic const rgb_color kBrightColor = {230, 230, 230, 255};
3513975ae8SAxel Dörflerstatic const rgb_color kDarkColor = {200, 200, 200, 255};
3613975ae8SAxel Dörflerstatic const rgb_color kSecondDeadKeyColor = {240, 240, 150, 255};
3713975ae8SAxel Dörflerstatic const rgb_color kDeadKeyColor = {152, 203, 255, 255};
383c394ad8SAxel Dörflerstatic const rgb_color kLitIndicatorColor = {116, 212, 83, 255};
3913975ae8SAxel Dörfler
4013975ae8SAxel Dörfler
41a073305cSJohn Scipionestatic bool
42a073305cSJohn Scipioneis_left_modifier_key(uint32 keyCode)
43a073305cSJohn Scipione{
44a073305cSJohn Scipione	return keyCode == 0x4b	// left shift
45a073305cSJohn Scipione		|| keyCode == 0x5d	// left command
46a073305cSJohn Scipione		|| keyCode == 0x5c	// left control
47a073305cSJohn Scipione		|| keyCode == 0x66;	// left option
48a073305cSJohn Scipione}
49a073305cSJohn Scipione
50a073305cSJohn Scipione
51a073305cSJohn Scipionestatic bool
52a073305cSJohn Scipioneis_right_modifier_key(uint32 keyCode)
53a073305cSJohn Scipione{
54a073305cSJohn Scipione	return keyCode == 0x56	// right shift
55a073305cSJohn Scipione		|| keyCode == 0x5f	// right command
56a073305cSJohn Scipione		|| keyCode == 0x60	// right control
57a073305cSJohn Scipione		|| keyCode == 0x67	// right option
58a073305cSJohn Scipione		|| keyCode == 0x68;	// menu
59a073305cSJohn Scipione}
60a073305cSJohn Scipione
61a073305cSJohn Scipione
62a073305cSJohn Scipionestatic bool
63a073305cSJohn Scipioneis_lock_key(uint32 keyCode)
64a073305cSJohn Scipione{
65a073305cSJohn Scipione	return keyCode == 0x3b	// caps lock
66a073305cSJohn Scipione		|| keyCode == 0x22	// num lock
67a073305cSJohn Scipione		|| keyCode == 0x0f;	// scroll lock
68a073305cSJohn Scipione}
69a073305cSJohn Scipione
70a073305cSJohn Scipione
71a073305cSJohn Scipionestatic bool
72a073305cSJohn Scipioneis_mappable_to_modifier(uint32 keyCode)
73a073305cSJohn Scipione{
74a073305cSJohn Scipione	return is_left_modifier_key(keyCode)
75a073305cSJohn Scipione		|| is_right_modifier_key(keyCode)
76a073305cSJohn Scipione		|| is_lock_key(keyCode);
77a073305cSJohn Scipione}
78a073305cSJohn Scipione
79a073305cSJohn Scipione
80a073305cSJohn Scipione//	#pragma mark - KeyboardLayoutView
81a073305cSJohn Scipione
82a073305cSJohn Scipione
8342176b84SAxel DörflerKeyboardLayoutView::KeyboardLayoutView(const char* name)
84c5bf6169SAxel Dörfler	:
85c5bf6169SAxel Dörfler	BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
8616dc221dSAxel Dörfler	fOffscreenBitmap(NULL),
8742176b84SAxel Dörfler	fKeymap(NULL),
88ebe98045SAxel Dörfler	fEditable(true),
8942176b84SAxel Dörfler	fModifiers(0),
9013975ae8SAxel Dörfler	fDeadKey(0),
9183656437SOliver Tappe	fButtons(0),
926aa7b635SAxel Dörfler	fDragKey(NULL),
93a6ad872bSAxel Dörfler	fDropTarget(NULL),
94a6ad872bSAxel Dörfler	fOldSize(0, 0)
9542176b84SAxel Dörfler{
9642176b84SAxel Dörfler	fLayout = new KeyboardLayout;
9742176b84SAxel Dörfler	memset(fKeyState, 0, sizeof(fKeyState));
9842176b84SAxel Dörfler
9942176b84SAxel Dörfler	SetEventMask(B_KEYBOARD_EVENTS);
10042176b84SAxel Dörfler}
10142176b84SAxel Dörfler
10242176b84SAxel Dörfler
10342176b84SAxel DörflerKeyboardLayoutView::~KeyboardLayoutView()
10442176b84SAxel Dörfler{
10516dc221dSAxel Dörfler	delete fOffscreenBitmap;
10642176b84SAxel Dörfler}
10742176b84SAxel Dörfler
10842176b84SAxel Dörfler
10942176b84SAxel Dörflervoid
11042176b84SAxel DörflerKeyboardLayoutView::SetKeyboardLayout(KeyboardLayout* layout)
11142176b84SAxel Dörfler{
11242176b84SAxel Dörfler	fLayout = layout;
1136ba46cedSJohn Scipione	_InitOffscreen();
11453c926beSAxel Dörfler	_LayoutKeyboard();
11542176b84SAxel Dörfler	Invalidate();
11642176b84SAxel Dörfler}
11742176b84SAxel Dörfler
11842176b84SAxel Dörfler
11942176b84SAxel Dörflervoid
12042176b84SAxel DörflerKeyboardLayoutView::SetKeymap(Keymap* keymap)
12142176b84SAxel Dörfler{
12242176b84SAxel Dörfler	fKeymap = keymap;
12342176b84SAxel Dörfler	Invalidate();
12442176b84SAxel Dörfler}
12542176b84SAxel Dörfler
12642176b84SAxel Dörfler
12753c926beSAxel Dörflervoid
12853c926beSAxel DörflerKeyboardLayoutView::SetTarget(BMessenger target)
12953c926beSAxel Dörfler{
13053c926beSAxel Dörfler	fTarget = target;
13153c926beSAxel Dörfler}
13253c926beSAxel Dörfler
13353c926beSAxel Dörfler
13453c926beSAxel Dörflervoid
1358f62243fSOliver TappeKeyboardLayoutView::SetBaseFont(const BFont& font)
13653c926beSAxel Dörfler{
1378f62243fSOliver Tappe	fBaseFont = font;
13853c926beSAxel Dörfler
13953c926beSAxel Dörfler	font_height fontHeight;
1408f62243fSOliver Tappe	fBaseFont.GetHeight(&fontHeight);
14153c926beSAxel Dörfler	fBaseFontHeight = fontHeight.ascent + fontHeight.descent;
1428f62243fSOliver Tappe	fBaseFontSize = fBaseFont.Size();
14353c926beSAxel Dörfler
14453c926beSAxel Dörfler	Invalidate();
14553c926beSAxel Dörfler}
14653c926beSAxel Dörfler
14753c926beSAxel Dörfler
14842176b84SAxel Dörflervoid
14942176b84SAxel DörflerKeyboardLayoutView::AttachedToWindow()
15042176b84SAxel Dörfler{
15116dc221dSAxel Dörfler	SetViewColor(B_TRANSPARENT_COLOR);
15242176b84SAxel Dörfler
1538f62243fSOliver Tappe	SetBaseFont(*be_plain_font);
15442176b84SAxel Dörfler	fSpecialFont = *be_fixed_font;
1553c394ad8SAxel Dörfler	fModifiers = modifiers();
15642176b84SAxel Dörfler}
15742176b84SAxel Dörfler
15842176b84SAxel Dörfler
15942176b84SAxel Dörflervoid
16042176b84SAxel DörflerKeyboardLayoutView::FrameResized(float width, float height)
16142176b84SAxel Dörfler{
16216dc221dSAxel Dörfler	_InitOffscreen();
16353c926beSAxel Dörfler	_LayoutKeyboard();
16442176b84SAxel Dörfler}
16542176b84SAxel Dörfler
16642176b84SAxel Dörfler
167d47410e0SOliver Tappevoid
168d47410e0SOliver TappeKeyboardLayoutView::WindowActivated(bool active)
169d47410e0SOliver Tappe{
170d47410e0SOliver Tappe	if (active)
171d47410e0SOliver Tappe		Invalidate();
172d47410e0SOliver Tappe}
173d47410e0SOliver Tappe
174246d3119SOliver Tappe
17542176b84SAxel DörflerBSize
17642176b84SAxel DörflerKeyboardLayoutView::MinSize()
17742176b84SAxel Dörfler{
178be09c2a1SAxel Dörfler	return BLayoutUtils::ComposeSize(ExplicitMinSize(), BSize(100, 50));
17942176b84SAxel Dörfler}
180be09c2a1SAxel Dörfler
18142176b84SAxel Dörfler
18242176b84SAxel Dörflervoid
18342176b84SAxel DörflerKeyboardLayoutView::KeyDown(const char* bytes, int32 numBytes)
18442176b84SAxel Dörfler{
18542176b84SAxel Dörfler	_KeyChanged(Window()->CurrentMessage());
18642176b84SAxel Dörfler}
18742176b84SAxel Dörfler
18842176b84SAxel Dörfler
18942176b84SAxel Dörflervoid
19042176b84SAxel DörflerKeyboardLayoutView::KeyUp(const char* bytes, int32 numBytes)
19142176b84SAxel Dörfler{
19242176b84SAxel Dörfler	_KeyChanged(Window()->CurrentMessage());
19342176b84SAxel Dörfler}
19442176b84SAxel Dörfler
19542176b84SAxel Dörfler
19642176b84SAxel Dörflervoid
19742176b84SAxel DörflerKeyboardLayoutView::MouseDown(BPoint point)
19842176b84SAxel Dörfler{
1998ba65ba1SAxel Dörfler	fClickPoint = point;
2006aa7b635SAxel Dörfler	fDragKey = NULL;
20184e80da0SAxel Dörfler	fDropPoint.x = -1;
2028ba65ba1SAxel Dörfler
20383656437SOliver Tappe	int32 buttons = 0;
20483656437SOliver Tappe	if (Looper() != NULL && Looper()->CurrentMessage() != NULL)
20583656437SOliver Tappe		Looper()->CurrentMessage()->FindInt32("buttons", &buttons);
20683656437SOliver Tappe
207173b5a68SJohn Scipione	Key* key = _KeyAt(point);
208173b5a68SJohn Scipione	if (fKeymap == NULL || key == NULL) {
209173b5a68SJohn Scipione		fButtons = buttons;
210173b5a68SJohn Scipione		return;
211173b5a68SJohn Scipione	}
212173b5a68SJohn Scipione
213ab0f7d66SJohn Scipione	if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0
214a073305cSJohn Scipione			|| ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0
215a073305cSJohn Scipione		&& (modifiers() & B_CONTROL_KEY) != 0)) {
216a073305cSJohn Scipione		// secondary mouse button, pop up a swap context menu
217a073305cSJohn Scipione		if (!is_mappable_to_modifier(key->code)) {
218b433c2adSJohn Scipione			// ToDo: Pop up a list of alternative characters to map
219b433c2adSJohn Scipione			// the key to. Currently we only add an option to remove the
220b433c2adSJohn Scipione			// current key mapping.
221b433c2adSJohn Scipione			BPopUpMenu* alternativesPopUp = new BPopUpMenu(
222b433c2adSJohn Scipione				"Alternatives pop up", true, true, B_ITEMS_IN_COLUMN);
223b433c2adSJohn Scipione			BMessage* message = new BMessage(kMsgUpdateNormalKeys);
224b433c2adSJohn Scipione			message->AddUInt32("keyCode", key->code);
225b433c2adSJohn Scipione			message->AddBool("unset", true);
226b433c2adSJohn Scipione			alternativesPopUp->AddItem(new BMenuItem(B_TRANSLATE("Remove"),
227b433c2adSJohn Scipione				message));
228b433c2adSJohn Scipione			alternativesPopUp->SetAsyncAutoDestruct(true);
229b433c2adSJohn Scipione			if (alternativesPopUp->SetTargetForItems(Window()) == B_OK)
230b433c2adSJohn Scipione				alternativesPopUp->Go(ConvertToScreen(point), true);
231b433c2adSJohn Scipione		} else {
232b433c2adSJohn Scipione			// pop up the modifier keys menu
233b433c2adSJohn Scipione			BPopUpMenu* modifiersPopUp = new BPopUpMenu("Modifiers pop up",
234b433c2adSJohn Scipione				true, true, B_ITEMS_IN_COLUMN);
235b433c2adSJohn Scipione			const key_map& map = fKeymap->Map();
236b433c2adSJohn Scipione			bool isLockKey = is_lock_key(key->code);
237b433c2adSJohn Scipione			BMenuItem* item = NULL;
238b433c2adSJohn Scipione
239b433c2adSJohn Scipione			if (is_left_modifier_key(key->code) || isLockKey) {
240b433c2adSJohn Scipione				item = _CreateSwapModifiersMenuItem(B_LEFT_SHIFT_KEY,
241b433c2adSJohn Scipione					isLockKey ? B_LEFT_SHIFT_KEY : B_SHIFT_KEY,
242b433c2adSJohn Scipione					map.left_shift_key, key->code);
243b433c2adSJohn Scipione				modifiersPopUp->AddItem(item);
244b433c2adSJohn Scipione				if (key->code == map.left_shift_key)
245b433c2adSJohn Scipione					item->SetMarked(true);
246b433c2adSJohn Scipione
247b433c2adSJohn Scipione				item = _CreateSwapModifiersMenuItem(B_LEFT_CONTROL_KEY,
248b433c2adSJohn Scipione					isLockKey ? B_LEFT_CONTROL_KEY : B_CONTROL_KEY,
249b433c2adSJohn Scipione					map.left_control_key, key->code);
250b433c2adSJohn Scipione				modifiersPopUp->AddItem(item);
251b433c2adSJohn Scipione				if (key->code == map.left_control_key)
252b433c2adSJohn Scipione					item->SetMarked(true);
253b433c2adSJohn Scipione
254b433c2adSJohn Scipione				item = _CreateSwapModifiersMenuItem(B_LEFT_OPTION_KEY,
255b433c2adSJohn Scipione					isLockKey ? B_LEFT_OPTION_KEY : B_OPTION_KEY,
256b433c2adSJohn Scipione					map.left_option_key, key->code);
257b433c2adSJohn Scipione				modifiersPopUp->AddItem(item);
258b433c2adSJohn Scipione				if (key->code == map.left_option_key)
259b433c2adSJohn Scipione					item->SetMarked(true);
260b433c2adSJohn Scipione
261b433c2adSJohn Scipione				item = _CreateSwapModifiersMenuItem(B_LEFT_COMMAND_KEY,
262b433c2adSJohn Scipione					isLockKey ? B_LEFT_COMMAND_KEY : B_COMMAND_KEY,
263b433c2adSJohn Scipione					map.left_command_key, key->code);
264b433c2adSJohn Scipione				modifiersPopUp->AddItem(item);
265b433c2adSJohn Scipione				if (key->code == map.left_command_key)
266b433c2adSJohn Scipione					item->SetMarked(true);
267b433c2adSJohn Scipione			}
268173b5a68SJohn Scipione
269b433c2adSJohn Scipione			if (is_right_modifier_key(key->code) || isLockKey) {
270b433c2adSJohn Scipione				if (isLockKey)
271b433c2adSJohn Scipione					modifiersPopUp->AddSeparatorItem();
272b433c2adSJohn Scipione
273b433c2adSJohn Scipione				item = _CreateSwapModifiersMenuItem(B_RIGHT_SHIFT_KEY,
274b433c2adSJohn Scipione					isLockKey ? B_RIGHT_SHIFT_KEY : B_SHIFT_KEY,
275b433c2adSJohn Scipione					map.right_shift_key, key->code);
276b433c2adSJohn Scipione				modifiersPopUp->AddItem(item);
277b433c2adSJohn Scipione				if (key->code == map.right_shift_key)
278b433c2adSJohn Scipione					item->SetMarked(true);
279b433c2adSJohn Scipione
280b433c2adSJohn Scipione				item = _CreateSwapModifiersMenuItem(B_RIGHT_CONTROL_KEY,
281b433c2adSJohn Scipione					isLockKey ? B_RIGHT_CONTROL_KEY : B_CONTROL_KEY,
282b433c2adSJohn Scipione					map.right_control_key, key->code);
283b433c2adSJohn Scipione				modifiersPopUp->AddItem(item);
284b433c2adSJohn Scipione				if (key->code == map.right_control_key)
285b433c2adSJohn Scipione					item->SetMarked(true);
286b433c2adSJohn Scipione			}
287173b5a68SJohn Scipione
288b433c2adSJohn Scipione			item = _CreateSwapModifiersMenuItem(B_MENU_KEY, B_MENU_KEY,
289b433c2adSJohn Scipione				map.menu_key, key->code);
290173b5a68SJohn Scipione			modifiersPopUp->AddItem(item);
291b433c2adSJohn Scipione			if (key->code == map.menu_key)
292173b5a68SJohn Scipione				item->SetMarked(true);
293173b5a68SJohn Scipione
294b433c2adSJohn Scipione			if (is_right_modifier_key(key->code) || isLockKey) {
295b433c2adSJohn Scipione				item = _CreateSwapModifiersMenuItem(B_RIGHT_OPTION_KEY,
296b433c2adSJohn Scipione					isLockKey ? B_RIGHT_OPTION_KEY : B_OPTION_KEY,
297b433c2adSJohn Scipione					map.right_option_key, key->code);
298b433c2adSJohn Scipione				modifiersPopUp->AddItem(item);
299b433c2adSJohn Scipione				if (key->code == map.right_option_key)
300b433c2adSJohn Scipione					item->SetMarked(true);
301b433c2adSJohn Scipione
302b433c2adSJohn Scipione				item = _CreateSwapModifiersMenuItem(B_RIGHT_COMMAND_KEY,
303b433c2adSJohn Scipione					isLockKey ? B_RIGHT_COMMAND_KEY : B_COMMAND_KEY,
304b433c2adSJohn Scipione					map.right_command_key, key->code);
305b433c2adSJohn Scipione				modifiersPopUp->AddItem(item);
306b433c2adSJohn Scipione				if (key->code == map.right_command_key)
307b433c2adSJohn Scipione					item->SetMarked(true);
308b433c2adSJohn Scipione			}
309173b5a68SJohn Scipione
310b433c2adSJohn Scipione			modifiersPopUp->AddSeparatorItem();
311173b5a68SJohn Scipione
312b433c2adSJohn Scipione			item = _CreateSwapModifiersMenuItem(B_CAPS_LOCK, B_CAPS_LOCK,
313b433c2adSJohn Scipione				map.caps_key, key->code);
314173b5a68SJohn Scipione			modifiersPopUp->AddItem(item);
315b433c2adSJohn Scipione			if (key->code == map.caps_key)
316173b5a68SJohn Scipione				item->SetMarked(true);
317173b5a68SJohn Scipione
318b433c2adSJohn Scipione			item = _CreateSwapModifiersMenuItem(B_NUM_LOCK, B_NUM_LOCK,
319b433c2adSJohn Scipione				map.num_key, key->code);
320173b5a68SJohn Scipione			modifiersPopUp->AddItem(item);
321b433c2adSJohn Scipione			if (key->code == map.num_key)
322173b5a68SJohn Scipione				item->SetMarked(true);
323173b5a68SJohn Scipione
324b433c2adSJohn Scipione			item = _CreateSwapModifiersMenuItem(B_SCROLL_LOCK, B_SCROLL_LOCK,
325b433c2adSJohn Scipione				map.scroll_key, key->code);
326173b5a68SJohn Scipione			modifiersPopUp->AddItem(item);
327b433c2adSJohn Scipione			if (key->code == map.scroll_key)
328173b5a68SJohn Scipione				item->SetMarked(true);
329173b5a68SJohn Scipione
330b433c2adSJohn Scipione			modifiersPopUp->SetAsyncAutoDestruct(true);
331b433c2adSJohn Scipione			if (modifiersPopUp->SetTargetForItems(Window()) == B_OK)
332b433c2adSJohn Scipione				modifiersPopUp->Go(ConvertToScreen(point), true);
333173b5a68SJohn Scipione		}
334173b5a68SJohn Scipione	} else if ((buttons & B_TERTIARY_MOUSE_BUTTON) != 0
33583656437SOliver Tappe		&& (fButtons & B_TERTIARY_MOUSE_BUTTON) == 0) {
336a073305cSJohn Scipione		// tertiary mouse button, toggle the "deadness" of dead keys
337173b5a68SJohn Scipione		bool isEnabled = false;
338ab0f7d66SJohn Scipione		uint8 deadKey = fKeymap->DeadKey(key->code, fModifiers, &isEnabled);
339173b5a68SJohn Scipione		if (deadKey > 0) {
340173b5a68SJohn Scipione			fKeymap->SetDeadKeyEnabled(key->code, fModifiers, !isEnabled);
341173b5a68SJohn Scipione			_InvalidateKey(key);
34283656437SOliver Tappe		}
34383656437SOliver Tappe	} else {
344173b5a68SJohn Scipione		// primary mouse button
345173b5a68SJohn Scipione		if (fKeymap->IsModifierKey(key->code)) {
34683656437SOliver Tappe			if (_KeyState(key->code)) {
34783656437SOliver Tappe				uint32 modifier = fKeymap->Modifier(key->code);
34883656437SOliver Tappe				if ((modifier & modifiers()) == 0) {
34983656437SOliver Tappe					_SetKeyState(key->code, false);
35083656437SOliver Tappe					fModifiers &= ~modifier;
35183656437SOliver Tappe					Invalidate();
35283656437SOliver Tappe				}
35383656437SOliver Tappe			} else {
35483656437SOliver Tappe				_SetKeyState(key->code, true);
35583656437SOliver Tappe				fModifiers |= fKeymap->Modifier(key->code);
356afa564ecSAxel Dörfler				Invalidate();
357afa564ecSAxel Dörfler			}
35883656437SOliver Tappe
35983656437SOliver Tappe			// TODO: if possible, we could handle the lock keys for real
360afa564ecSAxel Dörfler		} else {
361afa564ecSAxel Dörfler			_SetKeyState(key->code, true);
36283656437SOliver Tappe			_InvalidateKey(key);
363afa564ecSAxel Dörfler		}
3648ba65ba1SAxel Dörfler	}
36583656437SOliver Tappe
36683656437SOliver Tappe	fButtons = buttons;
36742176b84SAxel Dörfler}
36842176b84SAxel Dörfler
36942176b84SAxel Dörfler
37042176b84SAxel Dörflervoid
37142176b84SAxel DörflerKeyboardLayoutView::MouseUp(BPoint point)
37242176b84SAxel Dörfler{
3738ba65ba1SAxel Dörfler	Key* key = _KeyAt(fClickPoint);
37483656437SOliver Tappe
37583656437SOliver Tappe	int32 buttons = 0;
37683656437SOliver Tappe	if (Looper() != NULL && Looper()->CurrentMessage() != NULL)
37783656437SOliver Tappe		Looper()->CurrentMessage()->FindInt32("buttons", &buttons);
37883656437SOliver Tappe
379173b5a68SJohn Scipione	if (fKeymap == NULL || key == NULL) {
380173b5a68SJohn Scipione		fDragKey = NULL;
381173b5a68SJohn Scipione		return;
382173b5a68SJohn Scipione	}
383afa564ecSAxel Dörfler
384ab0f7d66SJohn Scipione	if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0
385ab0f7d66SJohn Scipione		|| ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0
386ab0f7d66SJohn Scipione			&& (modifiers() & B_CONTROL_KEY) != 0)) {
387ab0f7d66SJohn Scipione		; // do nothing
388ab0f7d66SJohn Scipione	} else if ((buttons & B_TERTIARY_MOUSE_BUTTON) != 0
389ab0f7d66SJohn Scipione		&& (fButtons & B_TERTIARY_MOUSE_BUTTON) == 0) {
390ab0f7d66SJohn Scipione		// toggle the "deadness" of dead keys via middle mouse button
391173b5a68SJohn Scipione		_SetKeyState(key->code, false);
392173b5a68SJohn Scipione		_InvalidateKey(key);
393173b5a68SJohn Scipione		fButtons = buttons;
394173b5a68SJohn Scipione	} else {
395173b5a68SJohn Scipione		// primary mouse button
396173b5a68SJohn Scipione		fButtons = buttons;
397be09c2a1SAxel Dörfler
398173b5a68SJohn Scipione		// modifier keys are sticky when used with the mouse
399173b5a68SJohn Scipione		if (fKeymap->IsModifierKey(key->code))
400173b5a68SJohn Scipione			return;
401be09c2a1SAxel Dörfler
402173b5a68SJohn Scipione		_SetKeyState(key->code, false);
40353c926beSAxel Dörfler
404173b5a68SJohn Scipione		if (_HandleDeadKey(key->code, fModifiers) && fDeadKey != 0)
405173b5a68SJohn Scipione			return;
40683656437SOliver Tappe
407173b5a68SJohn Scipione		_InvalidateKey(key);
408173b5a68SJohn Scipione
40943460996SJohn Scipione		if (fDragKey == NULL)
410173b5a68SJohn Scipione			_SendFakeKeyDown(key);
4118ba65ba1SAxel Dörfler	}
412173b5a68SJohn Scipione
41383656437SOliver Tappe	fDragKey = NULL;
41442176b84SAxel Dörfler}
41542176b84SAxel Dörfler
41642176b84SAxel Dörfler
41742176b84SAxel Dörflervoid
41842176b84SAxel DörflerKeyboardLayoutView::MouseMoved(BPoint point, uint32 transit,
41942176b84SAxel Dörfler	const BMessage* dragMessage)
42042176b84SAxel Dörfler{
42113975ae8SAxel Dörfler	if (fKeymap == NULL)
42213975ae8SAxel Dörfler		return;
42313975ae8SAxel Dörfler
424c5bf6169SAxel Dörfler	// prevent dragging for tertiary mouse button
42583656437SOliver Tappe	if ((fButtons & B_TERTIARY_MOUSE_BUTTON) != 0)
42683656437SOliver Tappe		return;
42783656437SOliver Tappe
42813975ae8SAxel Dörfler	if (dragMessage != NULL) {
429ebe98045SAxel Dörfler		if (fEditable) {
430ebe98045SAxel Dörfler			_InvalidateKey(fDropTarget);
431ebe98045SAxel Dörfler			fDropPoint = point;
43213975ae8SAxel Dörfler
433ebe98045SAxel Dörfler			_EvaluateDropTarget(point);
434ebe98045SAxel Dörfler		}
435afa564ecSAxel Dörfler
436afa564ecSAxel Dörfler		return;
437afa564ecSAxel Dörfler	}
43883656437SOliver Tappe
439afa564ecSAxel Dörfler	int32 buttons;
440afa564ecSAxel Dörfler	if (Window()->CurrentMessage() == NULL
441afa564ecSAxel Dörfler		|| Window()->CurrentMessage()->FindInt32("buttons", &buttons) != B_OK
442c959ce46SJohn Scipione		|| buttons == 0) {
443afa564ecSAxel Dörfler		return;
444c959ce46SJohn Scipione	}
445afa564ecSAxel Dörfler
4467e964405SJohn Scipione	if (fDragKey != NULL || !(fabs(point.x - fClickPoint.x) > 4
44713975ae8SAxel Dörfler		|| fabs(point.y - fClickPoint.y) > 4)) {
4487e964405SJohn Scipione		return;
4497e964405SJohn Scipione	}
45053c926beSAxel Dörfler
4517e964405SJohn Scipione	// start dragging
4527e964405SJohn Scipione	Key* key = _KeyAt(fClickPoint);
4537e964405SJohn Scipione	if (key == NULL)
4547e964405SJohn Scipione		return;
45513975ae8SAxel Dörfler
4567e964405SJohn Scipione	BRect frame = _FrameFor(key);
4577e964405SJohn Scipione	BPoint offset = fClickPoint - frame.LeftTop();
4587e964405SJohn Scipione	frame.OffsetTo(B_ORIGIN);
4597e964405SJohn Scipione
4607e964405SJohn Scipione	BRect rect = frame;
4617e964405SJohn Scipione	rect.right--;
4627e964405SJohn Scipione	rect.bottom--;
4637e964405SJohn Scipione	BBitmap* bitmap = new BBitmap(rect, B_RGBA32, true);
4647e964405SJohn Scipione	bitmap->Lock();
4657e964405SJohn Scipione
4667e964405SJohn Scipione	BView* view = new BView(rect, "drag", B_FOLLOW_NONE, 0);
4677e964405SJohn Scipione	bitmap->AddChild(view);
4687e964405SJohn Scipione
4697e964405SJohn Scipione	view->SetHighColor(0, 0, 0, 0);
4707e964405SJohn Scipione	view->FillRect(view->Bounds());
4717e964405SJohn Scipione	view->SetDrawingMode(B_OP_ALPHA);
4727e964405SJohn Scipione	view->SetHighColor(0, 0, 0, 128);
4737e964405SJohn Scipione	// set the level of transparency by value
4747e964405SJohn Scipione	view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE);
4757e964405SJohn Scipione	_DrawKey(view, frame, key, frame, false);
4767e964405SJohn Scipione
4777e964405SJohn Scipione	view->Sync();
4787e964405SJohn Scipione	bitmap->Unlock();
4797e964405SJohn Scipione
4807e964405SJohn Scipione	BMessage drag(B_MIME_DATA);
4817e964405SJohn Scipione	drag.AddInt32("key", key->code);
4827e964405SJohn Scipione
4837e964405SJohn Scipione	char* string;
4847e964405SJohn Scipione	int32 numBytes;
4857e964405SJohn Scipione	fKeymap->GetChars(key->code, fModifiers, fDeadKey, &string,
4867e964405SJohn Scipione		&numBytes);
4877e964405SJohn Scipione	if (string != NULL) {
4887e964405SJohn Scipione		drag.AddData("text/plain", B_MIME_DATA, string, numBytes);
4897e964405SJohn Scipione		delete[] string;
49013975ae8SAxel Dörfler	}
4917e964405SJohn Scipione
4927e964405SJohn Scipione	DragMessage(&drag, bitmap, B_OP_ALPHA, offset);
4937e964405SJohn Scipione	fDragKey = key;
4947e964405SJohn Scipione	fDragModifiers = fModifiers;
4957e964405SJohn Scipione
4967e964405SJohn Scipione	fKeyState[key->code / 8] &= ~(1 << (7 - (key->code & 7)));
4977e964405SJohn Scipione	_InvalidateKey(key);
49842176b84SAxel Dörfler}
49942176b84SAxel Dörfler
50042176b84SAxel Dörfler
50142176b84SAxel Dörflervoid
50242176b84SAxel DörflerKeyboardLayoutView::Draw(BRect updateRect)
50342176b84SAxel Dörfler{
504a6ad872bSAxel Dörfler	if (fOldSize != BSize(Bounds().Width(), Bounds().Height())) {
505a6ad872bSAxel Dörfler		_InitOffscreen();
506a6ad872bSAxel Dörfler		_LayoutKeyboard();
507a6ad872bSAxel Dörfler	}
508a6ad872bSAxel Dörfler
50916dc221dSAxel Dörfler	BView* view;
51016dc221dSAxel Dörfler	if (fOffscreenBitmap != NULL) {
51116dc221dSAxel Dörfler		view = fOffscreenView;
51216dc221dSAxel Dörfler		view->LockLooper();
51316dc221dSAxel Dörfler	} else
51416dc221dSAxel Dörfler		view = this;
51516dc221dSAxel Dörfler
51616dc221dSAxel Dörfler	// Draw background
51716dc221dSAxel Dörfler
51816dc221dSAxel Dörfler	if (Parent())
51916dc221dSAxel Dörfler		view->SetLowColor(Parent()->ViewColor());
52016dc221dSAxel Dörfler	else
52116dc221dSAxel Dörfler		view->SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
52216dc221dSAxel Dörfler
52316dc221dSAxel Dörfler	view->FillRect(updateRect, B_SOLID_LOW);
52416dc221dSAxel Dörfler
5253c394ad8SAxel Dörfler	// Draw keys
5263c394ad8SAxel Dörfler
52742176b84SAxel Dörfler	for (int32 i = 0; i < fLayout->CountKeys(); i++) {
52842176b84SAxel Dörfler		Key* key = fLayout->KeyAt(i);
52942176b84SAxel Dörfler
53016dc221dSAxel Dörfler		_DrawKey(view, updateRect, key, _FrameFor(key),
53113975ae8SAxel Dörfler			_IsKeyPressed(key->code));
53242176b84SAxel Dörfler	}
5333c394ad8SAxel Dörfler
5343c394ad8SAxel Dörfler	// Draw LED indicators
5353c394ad8SAxel Dörfler
5363c394ad8SAxel Dörfler	for (int32 i = 0; i < fLayout->CountIndicators(); i++) {
5373c394ad8SAxel Dörfler		Indicator* indicator = fLayout->IndicatorAt(i);
5383c394ad8SAxel Dörfler
53916dc221dSAxel Dörfler		_DrawIndicator(view, updateRect, indicator, _FrameFor(indicator->frame),
54016dc221dSAxel Dörfler			(fModifiers & indicator->modifier) != 0);
54116dc221dSAxel Dörfler	}
5423c394ad8SAxel Dörfler
54316dc221dSAxel Dörfler	if (fOffscreenBitmap != NULL) {
54416dc221dSAxel Dörfler		view->Sync();
54516dc221dSAxel Dörfler		view->UnlockLooper();
5463c394ad8SAxel Dörfler
54716dc221dSAxel Dörfler		DrawBitmapAsync(fOffscreenBitmap, BPoint(0, 0));
5483c394ad8SAxel Dörfler	}
54942176b84SAxel Dörfler}
55042176b84SAxel Dörfler
55142176b84SAxel Dörfler
55242176b84SAxel Dörflervoid
55342176b84SAxel DörflerKeyboardLayoutView::MessageReceived(BMessage* message)
55442176b84SAxel Dörfler{
555ebe98045SAxel Dörfler	if (message->WasDropped() && fEditable && fDropTarget != NULL
556ebe98045SAxel Dörfler		&& fKeymap != NULL) {
557ebe98045SAxel Dörfler		int32 keyCode;
5586aa7b635SAxel Dörfler		const char* data;
5596aa7b635SAxel Dörfler		ssize_t size;
5606aa7b635SAxel Dörfler		if (message->FindData("text/plain", B_MIME_DATA,
5616aa7b635SAxel Dörfler				(const void**)&data, &size) == B_OK) {
5627e5ffaa2SAxel Dörfler			// Automatically convert UTF-8 escaped strings (for example from
5637e5ffaa2SAxel Dörfler			// CharacterMap)
5647e5ffaa2SAxel Dörfler			int32 dataSize = 0;
5657e5ffaa2SAxel Dörfler			uint8 buffer[16];
5667e5ffaa2SAxel Dörfler			if (size > 3 && data[0] == '\\' && data[1] == 'x') {
5677e5ffaa2SAxel Dörfler				char tempBuffer[16];
5687e5ffaa2SAxel Dörfler				if (size > 15)
5697e5ffaa2SAxel Dörfler					size = 15;
5707e5ffaa2SAxel Dörfler				memcpy(tempBuffer, data, size);
5717e5ffaa2SAxel Dörfler				tempBuffer[size] = '\0';
5727e5ffaa2SAxel Dörfler				data = tempBuffer;
5737e5ffaa2SAxel Dörfler
5747e5ffaa2SAxel Dörfler				while (size > 3 && data[0] == '\\' && data[1] == 'x') {
5757e5ffaa2SAxel Dörfler					buffer[dataSize++] = strtoul(&data[2], NULL, 16);
5767e5ffaa2SAxel Dörfler					if ((buffer[dataSize - 1] & 0x80) == 0)
5777e5ffaa2SAxel Dörfler						break;
5787e5ffaa2SAxel Dörfler
5797e5ffaa2SAxel Dörfler					size -= 4;
5807e5ffaa2SAxel Dörfler					data += 4;
5817e5ffaa2SAxel Dörfler				}
5827e5ffaa2SAxel Dörfler				data = (const char*)buffer;
5837e5ffaa2SAxel Dörfler			} else if ((data[0] & 0xc0) != 0x80 && (data[0] & 0x80) != 0) {
5847e5ffaa2SAxel Dörfler				// only accept the first character UTF-8 character
5857e5ffaa2SAxel Dörfler				while (dataSize < size && (data[dataSize] & 0x80) != 0) {
5867e5ffaa2SAxel Dörfler					dataSize++;
5877e5ffaa2SAxel Dörfler				}
5887e5ffaa2SAxel Dörfler			} else if ((data[0] & 0x80) == 0) {
5897e5ffaa2SAxel Dörfler				// an ASCII character
5907e5ffaa2SAxel Dörfler				dataSize = 1;
5917e5ffaa2SAxel Dörfler			} else {
5927e5ffaa2SAxel Dörfler				// no valid character
5937e5ffaa2SAxel Dörfler				beep();
5947e5ffaa2SAxel Dörfler				return;
5957e5ffaa2SAxel Dörfler			}
5966aa7b635SAxel Dörfler
59784e80da0SAxel Dörfler			int32 buttons;
5986aa7b635SAxel Dörfler			if (!message->IsSourceRemote()
59984e80da0SAxel Dörfler				&& message->FindInt32("buttons", &buttons) == B_OK
600a62422fcSJohn Scipione				&& (buttons & B_PRIMARY_MOUSE_BUTTON) != 0
6016aa7b635SAxel Dörfler				&& message->FindInt32("key", &keyCode) == B_OK) {
6026aa7b635SAxel Dörfler				// switch keys if the dropped object came from us
6036aa7b635SAxel Dörfler				Key* key = _KeyForCode(keyCode);
60484e80da0SAxel Dörfler				if (key == NULL
605c959ce46SJohn Scipione					|| (key == fDropTarget && fDragModifiers == fModifiers)) {
6066aa7b635SAxel Dörfler					return;
607c959ce46SJohn Scipione				}
6086aa7b635SAxel Dörfler
6096aa7b635SAxel Dörfler				char* string;
6106aa7b635SAxel Dörfler				int32 numBytes;
6116aa7b635SAxel Dörfler				fKeymap->GetChars(fDropTarget->code, fModifiers, fDeadKey,
6126aa7b635SAxel Dörfler					&string, &numBytes);
6136aa7b635SAxel Dörfler				if (string != NULL) {
614ebe98045SAxel Dörfler					// switch keys
6156aa7b635SAxel Dörfler					fKeymap->SetKey(fDropTarget->code, fModifiers, fDeadKey,
6167e5ffaa2SAxel Dörfler						(const char*)data, dataSize);
61784e80da0SAxel Dörfler					fKeymap->SetKey(key->code, fDragModifiers, fDeadKey,
6186aa7b635SAxel Dörfler						string, numBytes);
6196aa7b635SAxel Dörfler					delete[] string;
620ebe98045SAxel Dörfler				} else if (fKeymap->IsModifierKey(fDropTarget->code)) {
621ebe98045SAxel Dörfler					// switch key with modifier
622ebe98045SAxel Dörfler					fKeymap->SetModifier(key->code,
623ebe98045SAxel Dörfler						fKeymap->Modifier(fDropTarget->code));
624ebe98045SAxel Dörfler					fKeymap->SetKey(fDropTarget->code, fModifiers, fDeadKey,
6257e5ffaa2SAxel Dörfler						(const char*)data, dataSize);
6266aa7b635SAxel Dörfler				}
6276aa7b635SAxel Dörfler			} else {
6286aa7b635SAxel Dörfler				// Send the old key to the target, so it's not lost entirely
6296aa7b635SAxel Dörfler				_SendFakeKeyDown(fDropTarget);
630be09c2a1SAxel Dörfler
6316aa7b635SAxel Dörfler				fKeymap->SetKey(fDropTarget->code, fModifiers, fDeadKey,
6327e5ffaa2SAxel Dörfler					(const char*)data, dataSize);
633be09c2a1SAxel Dörfler			}
634ebe98045SAxel Dörfler		} else if (!message->IsSourceRemote()
635ebe98045SAxel Dörfler			&& message->FindInt32("key", &keyCode) == B_OK) {
636ebe98045SAxel Dörfler			// Switch an unmapped key
637ebe98045SAxel Dörfler
638ebe98045SAxel Dörfler			Key* key = _KeyForCode(keyCode);
639ebe98045SAxel Dörfler			if (key != NULL && key == fDropTarget)
640ebe98045SAxel Dörfler				return;
641ebe98045SAxel Dörfler
642ebe98045SAxel Dörfler			uint32 modifier = fKeymap->Modifier(keyCode);
643ebe98045SAxel Dörfler
644ebe98045SAxel Dörfler			char* string;
645ebe98045SAxel Dörfler			int32 numBytes;
646ebe98045SAxel Dörfler			fKeymap->GetChars(fDropTarget->code, fModifiers, fDeadKey,
647ebe98045SAxel Dörfler				&string, &numBytes);
648ebe98045SAxel Dörfler			if (string != NULL) {
649ebe98045SAxel Dörfler				// switch key with modifier
650ebe98045SAxel Dörfler				fKeymap->SetModifier(fDropTarget->code, modifier);
651ebe98045SAxel Dörfler				fKeymap->SetKey(keyCode, fDragModifiers, fDeadKey,
652ebe98045SAxel Dörfler					string, numBytes);
653ebe98045SAxel Dörfler				delete[] string;
654ebe98045SAxel Dörfler			} else {
655ebe98045SAxel Dörfler				// switch modifier keys
656ebe98045SAxel Dörfler				fKeymap->SetModifier(keyCode,
657ebe98045SAxel Dörfler					fKeymap->Modifier(fDropTarget->code));
658ebe98045SAxel Dörfler				fKeymap->SetModifier(fDropTarget->code, modifier);
659ebe98045SAxel Dörfler			}
660c5bf6169SAxel Dörfler
661c5bf6169SAxel Dörfler			_InvalidateKey(fDragKey);
66253c926beSAxel Dörfler		}
6636aa7b635SAxel Dörfler
6646aa7b635SAxel Dörfler		_InvalidateKey(fDropTarget);
6656aa7b635SAxel Dörfler		fDropTarget = NULL;
66684e80da0SAxel Dörfler		fDropPoint.x = -1;
667a0205e0aSAxel Dörfler		return;
66853c926beSAxel Dörfler	}
66953c926beSAxel Dörfler
67042176b84SAxel Dörfler	switch (message->what) {
67142176b84SAxel Dörfler		case B_UNMAPPED_KEY_DOWN:
67242176b84SAxel Dörfler		case B_UNMAPPED_KEY_UP:
67342176b84SAxel Dörfler			_KeyChanged(message);
67442176b84SAxel Dörfler			break;
67542176b84SAxel Dörfler
67642176b84SAxel Dörfler		case B_MODIFIERS_CHANGED:
67716dc221dSAxel Dörfler		{
67816dc221dSAxel Dörfler			int32 newModifiers;
67916dc221dSAxel Dörfler			if (message->FindInt32("modifiers", &newModifiers) == B_OK
68016dc221dSAxel Dörfler				&& fModifiers != newModifiers) {
68116dc221dSAxel Dörfler				fModifiers = newModifiers;
68284e80da0SAxel Dörfler				_EvaluateDropTarget(fDropPoint);
683d47410e0SOliver Tappe				if (Window()->IsActive())
684d47410e0SOliver Tappe					Invalidate();
68584e80da0SAxel Dörfler			}
68642176b84SAxel Dörfler			break;
68716dc221dSAxel Dörfler		}
68842176b84SAxel Dörfler
68942176b84SAxel Dörfler		default:
69042176b84SAxel Dörfler			BView::MessageReceived(message);
69142176b84SAxel Dörfler			break;
69242176b84SAxel Dörfler	}
69342176b84SAxel Dörfler}
69442176b84SAxel Dörfler
69542176b84SAxel Dörfler
69616dc221dSAxel Dörflervoid
69716dc221dSAxel DörflerKeyboardLayoutView::_InitOffscreen()
69816dc221dSAxel Dörfler{
69916dc221dSAxel Dörfler	delete fOffscreenBitmap;
70016dc221dSAxel Dörfler	fOffscreenView = NULL;
70116dc221dSAxel Dörfler
70216dc221dSAxel Dörfler	fOffscreenBitmap = new(std::nothrow) BBitmap(Bounds(),
70316dc221dSAxel Dörfler		B_BITMAP_ACCEPTS_VIEWS, B_RGB32);
70416dc221dSAxel Dörfler	if (fOffscreenBitmap != NULL && fOffscreenBitmap->IsValid()) {
70516dc221dSAxel Dörfler		fOffscreenBitmap->Lock();
70616dc221dSAxel Dörfler		fOffscreenView = new(std::nothrow) BView(Bounds(), "offscreen view",
70716dc221dSAxel Dörfler			0, 0);
70816dc221dSAxel Dörfler		if (fOffscreenView != NULL) {
70916dc221dSAxel Dörfler			if (Parent() != NULL) {
71016dc221dSAxel Dörfler				fOffscreenView->SetViewColor(Parent()->ViewColor());
71116dc221dSAxel Dörfler			} else {
71216dc221dSAxel Dörfler				fOffscreenView->SetViewColor(
71316dc221dSAxel Dörfler					ui_color(B_PANEL_BACKGROUND_COLOR));
71416dc221dSAxel Dörfler			}
71516dc221dSAxel Dörfler
71616dc221dSAxel Dörfler			fOffscreenView->SetLowColor(fOffscreenView->ViewColor());
71716dc221dSAxel Dörfler			fOffscreenBitmap->AddChild(fOffscreenView);
71816dc221dSAxel Dörfler		}
71916dc221dSAxel Dörfler		fOffscreenBitmap->Unlock();
72016dc221dSAxel Dörfler	}
72116dc221dSAxel Dörfler
72216dc221dSAxel Dörfler	if (fOffscreenView == NULL) {
72316dc221dSAxel Dörfler		// something went wrong
72416dc221dSAxel Dörfler		delete fOffscreenBitmap;
72516dc221dSAxel Dörfler		fOffscreenBitmap = NULL;
72616dc221dSAxel Dörfler	}
72716dc221dSAxel Dörfler}
72816dc221dSAxel Dörfler
72916dc221dSAxel Dörfler
73053c926beSAxel Dörflervoid
73153c926beSAxel DörflerKeyboardLayoutView::_LayoutKeyboard()
73253c926beSAxel Dörfler{
73353c926beSAxel Dörfler	float factorX = Bounds().Width() / fLayout->Bounds().Width();
73453c926beSAxel Dörfler	float factorY = Bounds().Height() / fLayout->Bounds().Height();
73553c926beSAxel Dörfler
73653c926beSAxel Dörfler	fFactor = min_c(factorX, factorY);
73753c926beSAxel Dörfler	fOffset = BPoint((Bounds().Width() - fLayout->Bounds().Width()
73853c926beSAxel Dörfler			* fFactor) / 2,
73953c926beSAxel Dörfler		(Bounds().Height() - fLayout->Bounds().Height() * fFactor) / 2);
74053c926beSAxel Dörfler
74153c926beSAxel Dörfler	if (fLayout->DefaultKeySize().width < 11)
74253c926beSAxel Dörfler		fGap = 1;
74353c926beSAxel Dörfler	else
74453c926beSAxel Dörfler		fGap = 2;
745a6ad872bSAxel Dörfler
746a6ad872bSAxel Dörfler	fOldSize.width = Bounds().Width();
747a6ad872bSAxel Dörfler	fOldSize.height = Bounds().Height();
74853c926beSAxel Dörfler}
74953c926beSAxel Dörfler
75053c926beSAxel Dörfler
751a869d32eSAxel Dörflervoid
752d1996fdfSAxel DörflerKeyboardLayoutView::_DrawKeyButton(BView* view, BRect& rect, BRect updateRect,
753681c2e44SStephan Aßmus	rgb_color base, rgb_color background, bool pressed)
754a869d32eSAxel Dörfler{
755a884b43bSJohn Scipione	be_control_look->DrawButtonFrame(view, rect, updateRect, 4.0f, base,
756681c2e44SStephan Aßmus		background, pressed ? BControlLook::B_ACTIVATED : 0);
757a884b43bSJohn Scipione	be_control_look->DrawButtonBackground(view, rect, updateRect, 4.0f,
758a869d32eSAxel Dörfler		base, pressed ? BControlLook::B_ACTIVATED : 0);
759a869d32eSAxel Dörfler}
760a869d32eSAxel Dörfler
761a869d32eSAxel Dörfler
76213975ae8SAxel Dörflervoid
7636aa7b635SAxel DörflerKeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, const Key* key,
76413975ae8SAxel Dörfler	BRect rect, bool pressed)
76513975ae8SAxel Dörfler{
76613975ae8SAxel Dörfler	rgb_color base = key->dark ? kDarkColor : kBrightColor;
767681c2e44SStephan Aßmus	rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
768f0650dc9Slooncraz	rgb_color keyLabelColor = make_color(0, 0, 0, 255);
76913975ae8SAxel Dörfler	key_kind keyKind = kNormalKey;
77013975ae8SAxel Dörfler	int32 deadKey = 0;
771a869d32eSAxel Dörfler	bool secondDeadKey = false;
772