* 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:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user