* 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),
|
: BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
|
||||||
fOffscreenBitmap(NULL),
|
fOffscreenBitmap(NULL),
|
||||||
fKeymap(NULL),
|
fKeymap(NULL),
|
||||||
|
fEditable(true),
|
||||||
fModifiers(0),
|
fModifiers(0),
|
||||||
fDeadKey(0),
|
fDeadKey(0),
|
||||||
fDragKey(NULL),
|
fDragKey(NULL),
|
||||||
@@ -180,16 +181,17 @@ KeyboardLayoutView::MouseMoved(BPoint point, uint32 transit,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (dragMessage != NULL) {
|
if (dragMessage != NULL) {
|
||||||
_InvalidateKey(fDropTarget);
|
if (fEditable) {
|
||||||
fDropPoint = point;
|
_InvalidateKey(fDropTarget);
|
||||||
|
fDropPoint = point;
|
||||||
|
|
||||||
_EvaluateDropTarget(point);
|
_EvaluateDropTarget(point);
|
||||||
|
}
|
||||||
} else if (fDragKey == NULL && (fabs(point.x - fClickPoint.x) > 4
|
} else if (fDragKey == NULL && (fabs(point.x - fClickPoint.x) > 4
|
||||||
|| fabs(point.y - fClickPoint.y) > 4)) {
|
|| fabs(point.y - fClickPoint.y) > 4)) {
|
||||||
// start dragging
|
// start dragging
|
||||||
Key* key = _KeyAt(fClickPoint);
|
Key* key = _KeyAt(fClickPoint);
|
||||||
// TODO: remove once we support moving modifier keys around
|
if (key == NULL)
|
||||||
if (key == NULL || fKeymap->IsModifierKey(key->code))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BRect frame = _FrameFor(key);
|
BRect frame = _FrameFor(key);
|
||||||
@@ -294,7 +296,9 @@ KeyboardLayoutView::Draw(BRect updateRect)
|
|||||||
void
|
void
|
||||||
KeyboardLayoutView::MessageReceived(BMessage* message)
|
KeyboardLayoutView::MessageReceived(BMessage* message)
|
||||||
{
|
{
|
||||||
if (message->WasDropped() && fDropTarget != NULL && fKeymap != NULL) {
|
if (message->WasDropped() && fEditable && fDropTarget != NULL
|
||||||
|
&& fKeymap != NULL) {
|
||||||
|
int32 keyCode;
|
||||||
const char* data;
|
const char* data;
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
if (message->FindData("text/plain", B_MIME_DATA,
|
if (message->FindData("text/plain", B_MIME_DATA,
|
||||||
@@ -303,7 +307,6 @@ KeyboardLayoutView::MessageReceived(BMessage* message)
|
|||||||
if (data[size - 1] == '\0')
|
if (data[size - 1] == '\0')
|
||||||
size--;
|
size--;
|
||||||
|
|
||||||
int32 keyCode;
|
|
||||||
int32 buttons;
|
int32 buttons;
|
||||||
if (!message->IsSourceRemote()
|
if (!message->IsSourceRemote()
|
||||||
&& message->FindInt32("buttons", &buttons) == B_OK
|
&& message->FindInt32("buttons", &buttons) == B_OK
|
||||||
@@ -320,11 +323,18 @@ KeyboardLayoutView::MessageReceived(BMessage* message)
|
|||||||
fKeymap->GetChars(fDropTarget->code, fModifiers, fDeadKey,
|
fKeymap->GetChars(fDropTarget->code, fModifiers, fDeadKey,
|
||||||
&string, &numBytes);
|
&string, &numBytes);
|
||||||
if (string != NULL) {
|
if (string != NULL) {
|
||||||
|
// switch keys
|
||||||
fKeymap->SetKey(fDropTarget->code, fModifiers, fDeadKey,
|
fKeymap->SetKey(fDropTarget->code, fModifiers, fDeadKey,
|
||||||
(const char*)data, size);
|
(const char*)data, size);
|
||||||
fKeymap->SetKey(key->code, fDragModifiers, fDeadKey,
|
fKeymap->SetKey(key->code, fDragModifiers, fDeadKey,
|
||||||
string, numBytes);
|
string, numBytes);
|
||||||
delete[] string;
|
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 {
|
} else {
|
||||||
// Send the old key to the target, so it's not lost entirely
|
// 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,
|
fKeymap->SetKey(fDropTarget->code, fModifiers, fDeadKey,
|
||||||
(const char*)data, size);
|
(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);
|
_InvalidateKey(fDropTarget);
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ public:
|
|||||||
|
|
||||||
void SetFont(const BFont& font);
|
void SetFont(const BFont& font);
|
||||||
|
|
||||||
|
void SetEditable(bool editable);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void AttachedToWindow();
|
virtual void AttachedToWindow();
|
||||||
virtual void FrameResized(float width, float height);
|
virtual void FrameResized(float width, float height);
|
||||||
@@ -88,6 +90,7 @@ private:
|
|||||||
KeyboardLayout* fLayout;
|
KeyboardLayout* fLayout;
|
||||||
Keymap* fKeymap;
|
Keymap* fKeymap;
|
||||||
BMessenger fTarget;
|
BMessenger fTarget;
|
||||||
|
bool fEditable;
|
||||||
|
|
||||||
uint8 fKeyState[16];
|
uint8 fKeyState[16];
|
||||||
int32 fModifiers;
|
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.
|
//! Checks whether a key is a dead key.
|
||||||
uint8
|
uint8
|
||||||
Keymap::IsDeadKey(uint32 keyCode, uint32 modifiers)
|
Keymap::IsDeadKey(uint32 keyCode, uint32 modifiers)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ public:
|
|||||||
bool IsModifierKey(uint32 keyCode);
|
bool IsModifierKey(uint32 keyCode);
|
||||||
uint32 Modifier(uint32 keyCode);
|
uint32 Modifier(uint32 keyCode);
|
||||||
uint32 KeyForModifier(uint32 modifier);
|
uint32 KeyForModifier(uint32 modifier);
|
||||||
|
status_t SetModifier(uint32 keyCode, uint32 modifier);
|
||||||
|
|
||||||
uint8 IsDeadKey(uint32 keyCode, uint32 modifiers);
|
uint8 IsDeadKey(uint32 keyCode, uint32 modifiers);
|
||||||
bool IsDeadSecondKey(uint32 keyCode, uint32 modifiers,
|
bool IsDeadSecondKey(uint32 keyCode, uint32 modifiers,
|
||||||
@@ -46,6 +47,7 @@ public:
|
|||||||
int32 numBytes = -1);
|
int32 numBytes = -1);
|
||||||
|
|
||||||
const key_map& Map() const { return fKeys; }
|
const key_map& Map() const { return fKeys; }
|
||||||
|
key_map& Map() { return fKeys; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int32 _Offset(uint32 keyCode, uint32 modifiers,
|
int32 _Offset(uint32 keyCode, uint32 modifiers,
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ static const uint32 kMsgMenuFileSaveAs = 'mMFA';
|
|||||||
|
|
||||||
static const uint32 kChangeKeyboardLayout = 'cKyL';
|
static const uint32 kChangeKeyboardLayout = 'cKyL';
|
||||||
|
|
||||||
|
static const uint32 kMsgSwitchShortcuts = 'swSc';
|
||||||
|
|
||||||
static const uint32 kMsgMenuFontChanged = 'mMFC';
|
static const uint32 kMsgMenuFontChanged = 'mMFC';
|
||||||
|
|
||||||
static const uint32 kMsgSystemMapSelected = 'SmST';
|
static const uint32 kMsgSystemMapSelected = 'SmST';
|
||||||
@@ -61,6 +63,9 @@ KeymapWindow::KeymapWindow()
|
|||||||
|
|
||||||
fTextControl = new BTextControl("Sample and Clipboard:", "", NULL);
|
fTextControl = new BTextControl("Sample and Clipboard:", "", NULL);
|
||||||
|
|
||||||
|
fSwitchShortcutsButton = new BButton("switch", "",
|
||||||
|
new BMessage(kMsgSwitchShortcuts));
|
||||||
|
|
||||||
fUseButton = new BButton("useButton", "Use", new BMessage(kMsgUseKeymap));
|
fUseButton = new BButton("useButton", "Use", new BMessage(kMsgUseKeymap));
|
||||||
fRevertButton = new BButton("revertButton", "Revert",
|
fRevertButton = new BButton("revertButton", "Revert",
|
||||||
new BMessage(kMsgRevertKeymap));
|
new BMessage(kMsgRevertKeymap));
|
||||||
@@ -73,7 +78,9 @@ KeymapWindow::KeymapWindow()
|
|||||||
.Add(BGroupLayoutBuilder(B_VERTICAL, 10)
|
.Add(BGroupLayoutBuilder(B_VERTICAL, 10)
|
||||||
.Add(fKeyboardLayoutView)
|
.Add(fKeyboardLayoutView)
|
||||||
//.Add(new BStringView("text label", "Sample and Clipboard:"))
|
//.Add(new BStringView("text label", "Sample and Clipboard:"))
|
||||||
.Add(fTextControl)
|
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 10)
|
||||||
|
.Add(fTextControl)
|
||||||
|
.Add(fSwitchShortcutsButton))
|
||||||
.AddGlue(0.0)
|
.AddGlue(0.0)
|
||||||
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 10)
|
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 10)
|
||||||
.AddGlue(0.0)
|
.AddGlue(0.0)
|
||||||
@@ -146,6 +153,8 @@ KeymapWindow::KeymapWindow()
|
|||||||
fPreviousMap.Load(current->EntryRef());
|
fPreviousMap.Load(current->EntryRef());
|
||||||
fAppliedMap.Load(current->EntryRef());
|
fAppliedMap.Load(current->EntryRef());
|
||||||
|
|
||||||
|
_UpdateShortcutButton();
|
||||||
|
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,6 +238,10 @@ KeymapWindow::MessageReceived(BMessage* message)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kMsgSwitchShortcuts:
|
||||||
|
_SwitchShortcutKeys();
|
||||||
|
break;
|
||||||
|
|
||||||
case kMsgMenuFontChanged:
|
case kMsgMenuFontChanged:
|
||||||
{
|
{
|
||||||
BMenuItem *item = fFontMenu->FindMarked();
|
BMenuItem *item = fFontMenu->FindMarked();
|
||||||
@@ -428,11 +441,54 @@ KeymapWindow::_AddKeyboardLayouts(BMenu* menu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
void
|
||||||
KeymapWindow::_UpdateButtons()
|
KeymapWindow::_UpdateButtons()
|
||||||
{
|
{
|
||||||
fUseButton->SetEnabled(!fCurrentMap.Equals(fAppliedMap));
|
fUseButton->SetEnabled(!fCurrentMap.Equals(fAppliedMap));
|
||||||
fRevertButton->SetEnabled(!fCurrentMap.Equals(fPreviousMap));
|
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();
|
BView* _CreateMapLists();
|
||||||
void _AddKeyboardLayouts(BMenu* menu);
|
void _AddKeyboardLayouts(BMenu* menu);
|
||||||
|
|
||||||
|
void _UpdateShortcutButton();
|
||||||
void _UpdateButtons();
|
void _UpdateButtons();
|
||||||
|
void _SwitchShortcutKeys();
|
||||||
|
|
||||||
void _UseKeymap();
|
void _UseKeymap();
|
||||||
void _RevertKeymap();
|
void _RevertKeymap();
|
||||||
@@ -61,6 +63,7 @@ protected:
|
|||||||
BMenu* fFontMenu;
|
BMenu* fFontMenu;
|
||||||
KeyboardLayoutView* fKeyboardLayoutView;
|
KeyboardLayoutView* fKeyboardLayoutView;
|
||||||
BTextControl* fTextControl;
|
BTextControl* fTextControl;
|
||||||
|
BButton* fSwitchShortcutsButton;
|
||||||
|
|
||||||
Keymap fCurrentMap;
|
Keymap fCurrentMap;
|
||||||
Keymap fPreviousMap;
|
Keymap fPreviousMap;
|
||||||
|
|||||||
Reference in New Issue
Block a user