* Added ability to change modifier keys (per drag and drop).

* Added button to switch shortcut modifier keys.
* Added option to make the KeyboardLayoutView non-editable.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29801 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-03-30 13:19:11 +00:00
parent 91fbc75fd1
commit ebe98045d7
6 changed files with 155 additions and 9 deletions
+43 -7
View File
@@ -26,6 +26,7 @@ KeyboardLayoutView::KeyboardLayoutView(const char* name)
: BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
fOffscreenBitmap(NULL),
fKeymap(NULL),
fEditable(true),
fModifiers(0),
fDeadKey(0),
fDragKey(NULL),
@@ -180,16 +181,17 @@ KeyboardLayoutView::MouseMoved(BPoint point, uint32 transit,
return;
if (dragMessage != NULL) {
_InvalidateKey(fDropTarget);
fDropPoint = point;
if (fEditable) {
_InvalidateKey(fDropTarget);
fDropPoint = point;
_EvaluateDropTarget(point);
_EvaluateDropTarget(point);
}
} else if (fDragKey == NULL && (fabs(point.x - fClickPoint.x) > 4
|| fabs(point.y - fClickPoint.y) > 4)) {
// start dragging
Key* key = _KeyAt(fClickPoint);
// TODO: remove once we support moving modifier keys around
if (key == NULL || fKeymap->IsModifierKey(key->code))
if (key == NULL)
return;
BRect frame = _FrameFor(key);
@@ -294,7 +296,9 @@ KeyboardLayoutView::Draw(BRect updateRect)
void
KeyboardLayoutView::MessageReceived(BMessage* message)
{
if (message->WasDropped() && fDropTarget != NULL && fKeymap != NULL) {
if (message->WasDropped() && fEditable && fDropTarget != NULL
&& fKeymap != NULL) {
int32 keyCode;
const char* data;
ssize_t size;
if (message->FindData("text/plain", B_MIME_DATA,
@@ -303,7 +307,6 @@ KeyboardLayoutView::MessageReceived(BMessage* message)
if (data[size - 1] == '\0')
size--;
int32 keyCode;
int32 buttons;
if (!message->IsSourceRemote()
&& message->FindInt32("buttons", &buttons) == B_OK
@@ -320,11 +323,18 @@ KeyboardLayoutView::MessageReceived(BMessage* message)
fKeymap->GetChars(fDropTarget->code, fModifiers, fDeadKey,
&string, &numBytes);
if (string != NULL) {
// switch keys
fKeymap->SetKey(fDropTarget->code, fModifiers, fDeadKey,
(const char*)data, size);
fKeymap->SetKey(key->code, fDragModifiers, fDeadKey,
string, numBytes);
delete[] string;
} else if (fKeymap->IsModifierKey(fDropTarget->code)) {
// switch key with modifier
fKeymap->SetModifier(key->code,
fKeymap->Modifier(fDropTarget->code));
fKeymap->SetKey(fDropTarget->code, fModifiers, fDeadKey,
(const char*)data, size);
}
} else {
// Send the old key to the target, so it's not lost entirely
@@ -333,6 +343,32 @@ KeyboardLayoutView::MessageReceived(BMessage* message)
fKeymap->SetKey(fDropTarget->code, fModifiers, fDeadKey,
(const char*)data, size);
}
} else if (!message->IsSourceRemote()
&& message->FindInt32("key", &keyCode) == B_OK) {
// Switch an unmapped key
Key* key = _KeyForCode(keyCode);
if (key != NULL && key == fDropTarget)
return;
uint32 modifier = fKeymap->Modifier(keyCode);
char* string;
int32 numBytes;
fKeymap->GetChars(fDropTarget->code, fModifiers, fDeadKey,
&string, &numBytes);
if (string != NULL) {
// switch key with modifier
fKeymap->SetModifier(fDropTarget->code, modifier);
fKeymap->SetKey(keyCode, fDragModifiers, fDeadKey,
string, numBytes);
delete[] string;
} else {
// switch modifier keys
fKeymap->SetModifier(keyCode,
fKeymap->Modifier(fDropTarget->code));
fKeymap->SetModifier(fDropTarget->code, modifier);
}
}
_InvalidateKey(fDropTarget);
@@ -27,6 +27,8 @@ public:
void SetFont(const BFont& font);
void SetEditable(bool editable);
protected:
virtual void AttachedToWindow();
virtual void FrameResized(float width, float height);
@@ -88,6 +90,7 @@ private:
KeyboardLayout* fLayout;
Keymap* fKeymap;
BMessenger fTarget;
bool fEditable;
uint8 fKeyState[16];
int32 fModifiers;
+46
View File
@@ -305,6 +305,52 @@ Keymap::KeyForModifier(uint32 modifier)
}
status_t
Keymap::SetModifier(uint32 keyCode, uint32 modifier)
{
const uint32 kSingleKeys = B_LEFT_SHIFT_KEY | B_RIGHT_SHIFT_KEY
| B_LEFT_COMMAND_KEY | B_RIGHT_COMMAND_KEY | B_LEFT_CONTROL_KEY
| B_RIGHT_CONTROL_KEY | B_LEFT_OPTION_KEY | B_RIGHT_OPTION_KEY;
if ((modifier & kSingleKeys) != 0)
modifier &= kSingleKeys;
else if ((modifier & kModifierKeys) != 0)
modifier &= kModifierKeys;
if (modifier == B_CAPS_LOCK)
fKeys.caps_key = keyCode;
else if (modifier == B_NUM_LOCK)
fKeys.num_key = keyCode;
else if (modifier == B_SCROLL_LOCK)
fKeys.scroll_key = keyCode;
else if (modifier == B_LEFT_SHIFT_KEY)
fKeys.left_shift_key = keyCode;
else if (modifier == B_RIGHT_SHIFT_KEY)
fKeys.right_shift_key = keyCode;
else if (modifier == B_LEFT_COMMAND_KEY)
fKeys.left_command_key = keyCode;
else if (modifier == B_RIGHT_COMMAND_KEY)
fKeys.right_command_key = keyCode;
else if (modifier == B_LEFT_CONTROL_KEY)
fKeys.left_control_key = keyCode;
else if (modifier == B_RIGHT_CONTROL_KEY)
fKeys.right_control_key = keyCode;
else if (modifier == B_LEFT_OPTION_KEY)
fKeys.left_option_key = keyCode;
else if (modifier == B_RIGHT_OPTION_KEY)
fKeys.right_option_key = keyCode;
else if (modifier == B_MENU_KEY)
fKeys.menu_key = keyCode;
else
return B_BAD_VALUE;
if (fModificationMessage != NULL)
fTarget.SendMessage(fModificationMessage);
return B_OK;
}
//! Checks whether a key is a dead key.
uint8
Keymap::IsDeadKey(uint32 keyCode, uint32 modifiers)
+2
View File
@@ -31,6 +31,7 @@ public:
bool IsModifierKey(uint32 keyCode);
uint32 Modifier(uint32 keyCode);
uint32 KeyForModifier(uint32 modifier);
status_t SetModifier(uint32 keyCode, uint32 modifier);
uint8 IsDeadKey(uint32 keyCode, uint32 modifiers);
bool IsDeadSecondKey(uint32 keyCode, uint32 modifiers,
@@ -46,6 +47,7 @@ public:
int32 numBytes = -1);
const key_map& Map() const { return fKeys; }
key_map& Map() { return fKeys; }
private:
int32 _Offset(uint32 keyCode, uint32 modifiers,
+58 -2
View File
@@ -39,6 +39,8 @@ static const uint32 kMsgMenuFileSaveAs = 'mMFA';
static const uint32 kChangeKeyboardLayout = 'cKyL';
static const uint32 kMsgSwitchShortcuts = 'swSc';
static const uint32 kMsgMenuFontChanged = 'mMFC';
static const uint32 kMsgSystemMapSelected = 'SmST';
@@ -61,6 +63,9 @@ KeymapWindow::KeymapWindow()
fTextControl = new BTextControl("Sample and Clipboard:", "", NULL);
fSwitchShortcutsButton = new BButton("switch", "",
new BMessage(kMsgSwitchShortcuts));
fUseButton = new BButton("useButton", "Use", new BMessage(kMsgUseKeymap));
fRevertButton = new BButton("revertButton", "Revert",
new BMessage(kMsgRevertKeymap));
@@ -73,7 +78,9 @@ KeymapWindow::KeymapWindow()
.Add(BGroupLayoutBuilder(B_VERTICAL, 10)
.Add(fKeyboardLayoutView)
//.Add(new BStringView("text label", "Sample and Clipboard:"))
.Add(fTextControl)
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 10)
.Add(fTextControl)
.Add(fSwitchShortcutsButton))
.AddGlue(0.0)
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 10)
.AddGlue(0.0)
@@ -146,6 +153,8 @@ KeymapWindow::KeymapWindow()
fPreviousMap.Load(current->EntryRef());
fAppliedMap.Load(current->EntryRef());
_UpdateShortcutButton();
Unlock();
}
@@ -229,6 +238,10 @@ KeymapWindow::MessageReceived(BMessage* message)
break;
}
case kMsgSwitchShortcuts:
_SwitchShortcutKeys();
break;
case kMsgMenuFontChanged:
{
BMenuItem *item = fFontMenu->FindMarked();
@@ -428,11 +441,54 @@ KeymapWindow::_AddKeyboardLayouts(BMenu* menu)
}
void
void
KeymapWindow::_UpdateShortcutButton()
{
const char* label = "Switch Shortcut Keys";
if (fCurrentMap.KeyForModifier(B_LEFT_COMMAND_KEY) == 0x5d
&& fCurrentMap.KeyForModifier(B_LEFT_CONTROL_KEY) == 0x5c
&& fCurrentMap.KeyForModifier(B_RIGHT_OPTION_KEY) == 0x5f
&& fCurrentMap.KeyForModifier(B_RIGHT_CONTROL_KEY) == 0x60) {
label = "Switch Shortcut Keys To Windows/Linux Mode";
} else if (fCurrentMap.KeyForModifier(B_LEFT_COMMAND_KEY) == 0x5c
&& fCurrentMap.KeyForModifier(B_LEFT_CONTROL_KEY) == 0x5d
&& fCurrentMap.KeyForModifier(B_RIGHT_OPTION_KEY) == 0x60
&& fCurrentMap.KeyForModifier(B_RIGHT_CONTROL_KEY) == 0x5f) {
label = "Switch Shortcut Keys To Haiku Mode";
}
fSwitchShortcutsButton->SetLabel(label);
}
void
KeymapWindow::_UpdateButtons()
{
fUseButton->SetEnabled(!fCurrentMap.Equals(fAppliedMap));
fRevertButton->SetEnabled(!fCurrentMap.Equals(fPreviousMap));
_UpdateShortcutButton();
}
void
KeymapWindow::_SwitchShortcutKeys()
{
uint32 leftCommand = fCurrentMap.Map().left_command_key;
uint32 leftControl = fCurrentMap.Map().left_control_key;
uint32 rightOption = fCurrentMap.Map().right_option_key;
uint32 rightControl = fCurrentMap.Map().right_control_key;
// switch left side
fCurrentMap.Map().left_command_key = leftControl;
fCurrentMap.Map().left_control_key = leftCommand;
// switch right side
fCurrentMap.Map().right_option_key = rightControl;
fCurrentMap.Map().right_control_key = rightOption;
fKeyboardLayoutView->SetKeymap(&fCurrentMap);
_UpdateButtons();
}
+3
View File
@@ -39,7 +39,9 @@ protected:
BView* _CreateMapLists();
void _AddKeyboardLayouts(BMenu* menu);
void _UpdateShortcutButton();
void _UpdateButtons();
void _SwitchShortcutKeys();
void _UseKeymap();
void _RevertKeymap();
@@ -61,6 +63,7 @@ protected:
BMenu* fFontMenu;
KeyboardLayoutView* fKeyboardLayoutView;
BTextControl* fTextControl;
BButton* fSwitchShortcutsButton;
Keymap fCurrentMap;
Keymap fPreviousMap;