fat: Greatly simplify and clean up dosfs_get_file_map().
[haiku.git] / src / preferences / keymap / ModifierKeysWindow.cpp
blobdd1e5918aee39b032bb74406b6d8559038ad2eb6
1 /*
2 * Copyright 2011-2014 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * John Scipione, jscipione@gmail.com
7 */
10 #include "ModifierKeysWindow.h"
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
16 #include <Bitmap.h>
17 #include <Button.h>
18 #include <Catalog.h>
19 #include <CheckBox.h>
20 #include <FindDirectory.h>
21 #include <IconUtils.h>
22 #include <InterfaceDefs.h>
23 #include <LayoutBuilder.h>
24 #include <Locale.h>
25 #include <MenuField.h>
26 #include <MenuItem.h>
27 #include <Message.h>
28 #include <Path.h>
29 #include <PopUpMenu.h>
30 #include <Resources.h>
31 #include <Size.h>
32 #include <StringView.h>
34 #include "KeymapApplication.h"
37 #ifdef DEBUG_ALERT
38 # define FTRACE(x) fprintf(x)
39 #else
40 # define FTRACE(x) /* nothing */
41 #endif
44 enum {
45 SHIFT_KEY = 0x00000001,
46 CONTROL_KEY = 0x00000002,
47 OPTION_KEY = 0x00000004,
48 COMMAND_KEY = 0x00000008
51 enum {
52 MENU_ITEM_SHIFT = 0,
53 MENU_ITEM_CONTROL,
54 MENU_ITEM_OPTION,
55 MENU_ITEM_COMMAND,
56 MENU_ITEM_SEPERATOR,
57 MENU_ITEM_DISABLED
61 static const uint32 kMsgHideShowIcons = 'icon';
62 static const uint32 kMsgUpdateModifier = 'upmd';
63 static const uint32 kMsgApplyModifiers = 'apmd';
64 static const uint32 kMsgRevertModifiers = 'rvmd';
67 #undef B_TRANSLATION_CONTEXT
68 #define B_TRANSLATION_CONTEXT "Modifier keys window"
71 // #pragma mark - ConflictView
74 ConflictView::ConflictView(const char* name)
76 BView(BRect(0, 0, 15, 15), name, B_FOLLOW_NONE, B_WILL_DRAW),
77 fIcon(NULL),
78 fStopIcon(NULL),
79 fWarnIcon(NULL)
81 _FillIcons();
85 ConflictView::~ConflictView()
87 delete fStopIcon;
88 delete fWarnIcon;
92 void
93 ConflictView::Draw(BRect updateRect)
95 // Draw background
96 if (Parent())
97 SetLowColor(Parent()->ViewColor());
98 else
99 SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
101 FillRect(updateRect, B_SOLID_LOW);
103 if (fIcon == NULL)
104 return;
106 // Draw icon
107 SetDrawingMode(B_OP_ALPHA);
108 SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
109 DrawBitmapAsync(fIcon, BPoint(0, 0));
113 // get the icon
114 BBitmap*
115 ConflictView::Icon()
117 return fIcon;
121 // show or hide the stop icon
122 void
123 ConflictView::SetStopIcon(bool show)
125 fIcon = show ? fStopIcon : NULL;
126 const char* tip = show ? B_TRANSLATE("Error: duplicate keys")
127 : NULL;
128 SetToolTip(tip);
132 // show or hide the warn icon
133 void
134 ConflictView::SetWarnIcon(bool show)
136 fIcon = show ? fWarnIcon : NULL;
137 const char* tip = show
138 ? B_TRANSLATE("Warning: left and right key roles do not match")
139 : NULL;
140 SetToolTip(tip);
144 // #pragma mark - ConflictView private methods
147 // fill out the icons with the stop and warn symbols from app_server
148 void
149 ConflictView::_FillIcons()
151 // return if the icons have already been filled out
152 if (fStopIcon != NULL && fStopIcon->InitCheck() == B_OK
153 && fWarnIcon != NULL && fWarnIcon->InitCheck() == B_OK) {
154 return;
157 BPath path;
158 status_t status = find_directory(B_BEOS_SERVERS_DIRECTORY, &path);
159 if (status < B_OK) {
160 FTRACE((stderr,
161 "_FillIcons() - find_directory failed: %s\n",
162 strerror(status)));
163 return;
166 path.Append("app_server");
167 BFile file;
168 status = file.SetTo(path.Path(), B_READ_ONLY);
169 if (status < B_OK) {
170 FTRACE((stderr,
171 "_FillIcons() - BFile init failed: %s\n",
172 strerror(status)));
173 return;
176 BResources resources;
177 status = resources.SetTo(&file);
178 if (status < B_OK) {
179 FTRACE((stderr,
180 "_FillIcons() - BResources init failed: %s\n",
181 strerror(status)));
182 return;
185 size_t size = 0;
187 if (fStopIcon == NULL) {
188 // Allocate the fStopIcon bitmap
189 fStopIcon = new (std::nothrow) BBitmap(BRect(0, 0, 15, 15), 0,
190 B_RGBA32);
191 if (fStopIcon->InitCheck() != B_OK) {
192 FTRACE((stderr, "_FillIcons() - No memory for stop bitmap\n"));
193 delete fStopIcon;
194 fStopIcon = NULL;
195 return;
198 // load stop icon bitmap from app_server
199 const uint8* stopVector
200 = (const uint8*)resources.LoadResource(B_VECTOR_ICON_TYPE, "stop",
201 &size);
202 if (stopVector == NULL
203 || BIconUtils::GetVectorIcon(stopVector, size, fStopIcon)
204 != B_OK) {
205 delete fStopIcon;
206 fStopIcon = NULL;
210 if (fWarnIcon == NULL) {
211 // Allocate the fWarnIcon bitmap
212 fWarnIcon = new (std::nothrow) BBitmap(BRect(0, 0, 15, 15), 0,
213 B_RGBA32);
214 if (fWarnIcon->InitCheck() != B_OK) {
215 FTRACE((stderr, "_FillIcons() - No memory for warn bitmap\n"));
216 delete fWarnIcon;
217 fWarnIcon = NULL;
218 return;
221 // load warn icon bitmap from app_server
222 const uint8* warnVector
223 = (const uint8*)resources.LoadResource(B_VECTOR_ICON_TYPE, "warn",
224 &size);
225 if (warnVector == NULL
226 || BIconUtils::GetVectorIcon(warnVector, size, fWarnIcon)
227 != B_OK) {
228 delete fWarnIcon;
229 fWarnIcon = NULL;
235 // #pragma mark - ModifierKeysWindow
238 ModifierKeysWindow::ModifierKeysWindow()
240 BWindow(BRect(0, 0, 360, 220), B_TRANSLATE("Modifier keys"),
241 B_FLOATING_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE
242 | B_AUTO_UPDATE_SIZE_LIMITS)
244 get_key_map(&fCurrentMap, &fCurrentBuffer);
245 get_key_map(&fSavedMap, &fSavedBuffer);
247 BStringView* keyRole = new BStringView("key role",
248 B_TRANSLATE_COMMENT("Role", "As in the role of a modifier key"));
249 keyRole->SetAlignment(B_ALIGN_RIGHT);
250 keyRole->SetFont(be_bold_font);
252 BStringView* keyLabel = new BStringView("key label",
253 B_TRANSLATE_COMMENT("Key", "As in a computer keyboard key"));
254 keyLabel->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
255 keyLabel->SetFont(be_bold_font);
257 BMenuField* shiftMenuField = _CreateShiftMenuField();
258 shiftMenuField->SetAlignment(B_ALIGN_RIGHT);
260 BMenuField* controlMenuField = _CreateControlMenuField();
261 controlMenuField->SetAlignment(B_ALIGN_RIGHT);
263 BMenuField* optionMenuField = _CreateOptionMenuField();
264 optionMenuField->SetAlignment(B_ALIGN_RIGHT);
266 BMenuField* commandMenuField = _CreateCommandMenuField();
267 commandMenuField->SetAlignment(B_ALIGN_RIGHT);
269 fShiftConflictView = new ConflictView("shift warning view");
270 fShiftConflictView->SetExplicitMaxSize(BSize(15, 15));
272 fControlConflictView = new ConflictView("control warning view");
273 fControlConflictView->SetExplicitMaxSize(BSize(15, 15));
275 fOptionConflictView = new ConflictView("option warning view");
276 fOptionConflictView->SetExplicitMaxSize(BSize(15, 15));
278 fCommandConflictView = new ConflictView("command warning view");
279 fCommandConflictView->SetExplicitMaxSize(BSize(15, 15));
281 fCancelButton = new BButton("cancelButton", B_TRANSLATE("Cancel"),
282 new BMessage(B_QUIT_REQUESTED));
284 fRevertButton = new BButton("revertButton", B_TRANSLATE("Revert"),
285 new BMessage(kMsgRevertModifiers));
286 fRevertButton->SetEnabled(false);
288 fOkButton = new BButton("okButton", B_TRANSLATE("Set modifier keys"),
289 new BMessage(kMsgApplyModifiers));
290 fOkButton->MakeDefault(true);
292 BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_SMALL_SPACING)
293 .AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING)
294 .Add(keyRole, 0, 0)
295 .Add(keyLabel, 1, 0)
297 .Add(shiftMenuField->CreateLabelLayoutItem(), 0, 1)
298 .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING, 1, 1)
299 .Add(shiftMenuField->CreateMenuBarLayoutItem())
300 .Add(fShiftConflictView)
301 .End()
303 .Add(controlMenuField->CreateLabelLayoutItem(), 0, 2)
304 .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING, 1, 2)
305 .Add(controlMenuField->CreateMenuBarLayoutItem())
306 .Add(fControlConflictView)
307 .End()
309 .Add(optionMenuField->CreateLabelLayoutItem(), 0, 3)
310 .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING, 1, 3)
311 .Add(optionMenuField->CreateMenuBarLayoutItem())
312 .Add(fOptionConflictView)
313 .End()
315 .Add(commandMenuField->CreateLabelLayoutItem(), 0, 4)
316 .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING, 1, 4)
317 .Add(commandMenuField->CreateMenuBarLayoutItem())
318 .Add(fCommandConflictView)
319 .End()
320 .End()
321 .AddGlue()
322 .AddGroup(B_HORIZONTAL)
323 .Add(fCancelButton)
324 .AddGlue()
325 .Add(fRevertButton)
326 .Add(fOkButton)
327 .End()
328 .SetInsets(B_USE_DEFAULT_SPACING)
329 .End();
331 _MarkMenuItems();
332 _ValidateDuplicateKeys();
334 PostMessage(kMsgHideShowIcons);
338 ModifierKeysWindow::~ModifierKeysWindow()
340 be_app->PostMessage(kMsgCloseModifierKeysWindow);
344 void
345 ModifierKeysWindow::MessageReceived(BMessage* message)
347 switch (message->what) {
348 case kMsgHideShowIcons:
349 _HideShowIcons();
350 break;
352 case kMsgUpdateModifier:
354 int32 menuitem = MENU_ITEM_SHIFT;
355 int32 key = -1;
357 for (; menuitem <= MENU_ITEM_COMMAND; menuitem++) {
358 if (message->FindInt32(_KeyToString(menuitem), &key) == B_OK)
359 break;
362 if (key == -1)
363 return;
365 // menuitem contains the item we want to set
366 // key contains the item we want to set it to.
368 switch (menuitem) {
369 case MENU_ITEM_SHIFT:
370 fCurrentMap->left_shift_key = _KeyToKeyCode(key);
371 fCurrentMap->right_shift_key = _KeyToKeyCode(key, true);
372 break;
374 case MENU_ITEM_CONTROL:
375 fCurrentMap->left_control_key = _KeyToKeyCode(key);
376 fCurrentMap->right_control_key = _KeyToKeyCode(key, true);
377 break;
379 case MENU_ITEM_OPTION:
380 fCurrentMap->left_option_key = _KeyToKeyCode(key);
381 fCurrentMap->right_option_key = _KeyToKeyCode(key, true);
382 break;
384 case MENU_ITEM_COMMAND:
385 fCurrentMap->left_command_key = _KeyToKeyCode(key);
386 fCurrentMap->right_command_key = _KeyToKeyCode(key, true);
387 break;
390 _MarkMenuItems();
391 _ValidateDuplicateKeys();
392 _HideShowIcons();
394 // enable/disable revert button
395 fRevertButton->SetEnabled(
396 memcmp(fCurrentMap, fSavedMap, sizeof(key_map)));
397 break;
400 // OK button
401 case kMsgApplyModifiers:
403 // if duplicate modifiers are found, don't update
404 if (_DuplicateKeys() != 0)
405 break;
407 BMessage* updateModifiers = new BMessage(kMsgUpdateModifierKeys);
409 if (fCurrentMap->left_shift_key != fSavedMap->left_shift_key) {
410 updateModifiers->AddUInt32("left_shift_key",
411 fCurrentMap->left_shift_key);
414 if (fCurrentMap->right_shift_key != fSavedMap->right_shift_key) {
415 updateModifiers->AddUInt32("right_shift_key",
416 fCurrentMap->right_shift_key);
419 if (fCurrentMap->left_control_key != fSavedMap->left_control_key) {
420 updateModifiers->AddUInt32("left_control_key",
421 fCurrentMap->left_control_key);
424 if (fCurrentMap->right_control_key
425 != fSavedMap->right_control_key) {
426 updateModifiers->AddUInt32("right_control_key",
427 fCurrentMap->right_control_key);
430 if (fCurrentMap->left_option_key != fSavedMap->left_option_key) {
431 updateModifiers->AddUInt32("left_option_key",
432 fCurrentMap->left_option_key);
435 if (fCurrentMap->right_option_key != fSavedMap->right_option_key) {
436 updateModifiers->AddUInt32("right_option_key",
437 fCurrentMap->right_option_key);
440 if (fCurrentMap->left_command_key != fSavedMap->left_command_key) {
441 updateModifiers->AddUInt32("left_command_key",
442 fCurrentMap->left_command_key);
445 if (fCurrentMap->right_command_key
446 != fSavedMap->right_command_key) {
447 updateModifiers->AddUInt32("right_command_key",
448 fCurrentMap->right_command_key);
451 // KeymapWindow updates the modifiers
452 be_app->PostMessage(updateModifiers);
454 // we are done here, close the window
455 this->PostMessage(B_QUIT_REQUESTED);
456 break;
459 // Revert button
460 case kMsgRevertModifiers:
461 memcpy(fCurrentMap, fSavedMap, sizeof(key_map));
463 _MarkMenuItems();
464 _ValidateDuplicateKeys();
465 _HideShowIcons();
467 fRevertButton->SetEnabled(false);
468 break;
470 default:
471 BWindow::MessageReceived(message);
476 // #pragma mark - ModifierKeysWindow private methods
479 BMenuField*
480 ModifierKeysWindow::_CreateShiftMenuField()
482 fShiftMenu = new BPopUpMenu(
483 B_TRANSLATE_NOCOLLECT(_KeyToString(MENU_ITEM_SHIFT)), true, true);
485 for (int32 key = MENU_ITEM_SHIFT; key <= MENU_ITEM_DISABLED; key++) {
486 if (key == MENU_ITEM_SEPERATOR) {
487 // add separator item
488 BSeparatorItem* separator = new BSeparatorItem;
489 fShiftMenu->AddItem(separator, MENU_ITEM_SEPERATOR);
490 continue;
493 BMessage* message = new BMessage(kMsgUpdateModifier);
494 message->AddInt32(_KeyToString(MENU_ITEM_SHIFT), key);
495 BMenuItem* item = new BMenuItem(
496 B_TRANSLATE_NOCOLLECT(_KeyToString(key)), message);
498 fShiftMenu->AddItem(item, key);
501 fShiftMenu->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH,
502 B_ALIGN_VERTICAL_UNSET));
504 return new BMenuField(B_TRANSLATE_COMMENT("Shift:", "Shift key role name"),
505 fShiftMenu);
509 BMenuField*
510 ModifierKeysWindow::_CreateControlMenuField()
512 fControlMenu = new BPopUpMenu(
513 B_TRANSLATE_NOCOLLECT(_KeyToString(MENU_ITEM_CONTROL)), true, true);
515 for (int32 key = MENU_ITEM_SHIFT; key <= MENU_ITEM_DISABLED; key++) {
516 if (key == MENU_ITEM_SEPERATOR) {
517 // add separator item
518 BSeparatorItem* separator = new BSeparatorItem;
519 fControlMenu->AddItem(separator, MENU_ITEM_SEPERATOR);
520 continue;
523 BMessage* message = new BMessage(kMsgUpdateModifier);
524 message->AddInt32(_KeyToString(MENU_ITEM_CONTROL), key);
525 BMenuItem* item = new BMenuItem(
526 B_TRANSLATE_NOCOLLECT(_KeyToString(key)), message);
528 fControlMenu->AddItem(item, key);
531 fControlMenu->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH,
532 B_ALIGN_VERTICAL_UNSET));
534 return new BMenuField(B_TRANSLATE_COMMENT("Control:",
535 "Control key role name"), fControlMenu);
539 BMenuField*
540 ModifierKeysWindow::_CreateOptionMenuField()
542 fOptionMenu = new BPopUpMenu(
543 B_TRANSLATE_NOCOLLECT(_KeyToString(MENU_ITEM_OPTION)), true, true);
545 for (int32 key = MENU_ITEM_SHIFT; key <= MENU_ITEM_DISABLED; key++) {
546 if (key == MENU_ITEM_SEPERATOR) {
547 // add separator item
548 BSeparatorItem* separator = new BSeparatorItem;
549 fOptionMenu->AddItem(separator, MENU_ITEM_SEPERATOR);
550 continue;
553 BMessage* message = new BMessage(kMsgUpdateModifier);
554 message->AddInt32(_KeyToString(MENU_ITEM_OPTION), key);
555 BMenuItem* item = new BMenuItem(
556 B_TRANSLATE_NOCOLLECT(_KeyToString(key)), message);
558 fOptionMenu->AddItem(item, key);
561 fOptionMenu->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH,
562 B_ALIGN_VERTICAL_UNSET));
564 return new BMenuField(B_TRANSLATE_COMMENT("Option:",
565 "Option key role name"), fOptionMenu);
569 BMenuField*
570 ModifierKeysWindow::_CreateCommandMenuField()
572 fCommandMenu = new BPopUpMenu(
573 B_TRANSLATE_NOCOLLECT(_KeyToString(MENU_ITEM_COMMAND)), true, true);
575 for (int32 key = MENU_ITEM_SHIFT; key <= MENU_ITEM_DISABLED; key++) {
576 if (key == MENU_ITEM_SEPERATOR) {
577 // add separator item
578 BSeparatorItem* separator = new BSeparatorItem;
579 fCommandMenu->AddItem(separator, MENU_ITEM_SEPERATOR);
580 continue;
583 BMessage* message = new BMessage(kMsgUpdateModifier);
584 message->AddInt32(_KeyToString(MENU_ITEM_COMMAND), key);
585 BMenuItem* item = new BMenuItem(
586 B_TRANSLATE_NOCOLLECT(_KeyToString(key)), message);
587 fCommandMenu->AddItem(item, key);
590 fCommandMenu->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH,
591 B_ALIGN_VERTICAL_UNSET));
593 return new BMenuField(B_TRANSLATE_COMMENT("Command:",
594 "Command key role name"), fCommandMenu);
598 void
599 ModifierKeysWindow::_MarkMenuItems()
601 for (int32 key = MENU_ITEM_SHIFT; key <= MENU_ITEM_DISABLED; key++) {
602 if (key == MENU_ITEM_SEPERATOR)
603 continue;
605 if (fCurrentMap->left_shift_key == _KeyToKeyCode(key)
606 && fCurrentMap->right_shift_key == _KeyToKeyCode(key, true)) {
607 fShiftMenu->ItemAt(key)->SetMarked(true);
610 if (fCurrentMap->left_control_key == _KeyToKeyCode(key)
611 && fCurrentMap->right_control_key == _KeyToKeyCode(key, true)) {
612 fControlMenu->ItemAt(key)->SetMarked(true);
615 if (fCurrentMap->left_option_key == _KeyToKeyCode(key)
616 && fCurrentMap->right_option_key == _KeyToKeyCode(key, true)) {
617 fOptionMenu->ItemAt(key)->SetMarked(true);
620 if (fCurrentMap->left_command_key == _KeyToKeyCode(key)
621 && fCurrentMap->right_command_key == _KeyToKeyCode(key, true)) {
622 fCommandMenu->ItemAt(key)->SetMarked(true);
626 // Set the warning icon if not marked
627 BBitmap* shiftIcon = fShiftConflictView->Icon();
628 BBitmap* controlIcon = fControlConflictView->Icon();
629 BBitmap* optionIcon = fOptionConflictView->Icon();
630 BBitmap* commandIcon = fCommandConflictView->Icon();
632 fShiftConflictView->SetWarnIcon(fShiftMenu->FindMarked() == NULL);
633 fControlConflictView->SetWarnIcon(fControlMenu->FindMarked() == NULL);
634 fOptionConflictView->SetWarnIcon(fOptionMenu->FindMarked() == NULL);
635 fCommandConflictView->SetWarnIcon(fCommandMenu->FindMarked() == NULL);
637 // if there was a change invalidate the view
638 if (shiftIcon != fShiftConflictView->Icon())
639 fShiftConflictView->Invalidate();
641 if (controlIcon != fControlConflictView->Icon())
642 fControlConflictView->Invalidate();
644 if (optionIcon != fOptionConflictView->Icon())
645 fOptionConflictView->Invalidate();
647 if (commandIcon != fCommandConflictView->Icon())
648 fCommandConflictView->Invalidate();
652 // get the string for a modifier key
653 const char*
654 ModifierKeysWindow::_KeyToString(int32 key)
656 switch (key) {
657 case MENU_ITEM_SHIFT:
658 return B_TRANSLATE_COMMENT("Shift key",
659 "Label of key above Ctrl, usually Shift");
661 case MENU_ITEM_CONTROL:
662 return B_TRANSLATE_COMMENT("Ctrl key",
663 "Label of key farthest from the spacebar, usually Ctrl"
664 "e.g. Strg for German keyboard");
666 case MENU_ITEM_OPTION:
667 return B_TRANSLATE_COMMENT("Win/Cmd key",
668 "Label of the \"Windows\" key (PC)/Command key (Mac)");
670 case MENU_ITEM_COMMAND:
671 return B_TRANSLATE_COMMENT("Alt/Opt key",
672 "Label of Alt key (PC)/Option key (Mac)");
674 case MENU_ITEM_DISABLED:
675 return B_TRANSLATE_COMMENT("Disabled", "Do nothing");
678 return "";
682 // get the keycode for a modifier key
683 uint32
684 ModifierKeysWindow::_KeyToKeyCode(int32 key, bool right)
686 switch (key) {
687 case MENU_ITEM_SHIFT:
688 if (right)
689 return 0x56;
690 return 0x4b;
692 case MENU_ITEM_CONTROL:
693 if (right)
694 return 0x60;
695 return 0x5c;
697 case MENU_ITEM_OPTION:
698 if (right)
699 return 0x67;
700 return 0x66;
702 case MENU_ITEM_COMMAND:
703 if (right)
704 return 0x5f;
705 return 0x5d;
707 case MENU_ITEM_DISABLED:
708 return 0;
711 return 0;
715 // validate duplicate keys
716 void
717 ModifierKeysWindow::_ValidateDuplicateKeys()
719 uint32 dupMask = _DuplicateKeys();
721 BBitmap* shiftIcon = fShiftConflictView->Icon();
722 BBitmap* controlIcon = fControlConflictView->Icon();
723 BBitmap* optionIcon = fOptionConflictView->Icon();
724 BBitmap* commandIcon = fCommandConflictView->Icon();
726 if ((dupMask & SHIFT_KEY) != 0)
727 fShiftConflictView->SetStopIcon(true);
729 if ((dupMask & CONTROL_KEY) != 0)
730 fControlConflictView->SetStopIcon(true);
732 if ((dupMask & OPTION_KEY) != 0)
733 fOptionConflictView->SetStopIcon(true);
735 if ((dupMask & COMMAND_KEY) != 0)
736 fCommandConflictView->SetStopIcon(true);
738 fOkButton->SetEnabled(dupMask == 0);
740 // if there was a change invalidate the view
741 if (shiftIcon != fShiftConflictView->Icon())
742 fShiftConflictView->Invalidate();
744 if (controlIcon != fControlConflictView->Icon())
745 fControlConflictView->Invalidate();
747 if (optionIcon != fOptionConflictView->Icon())
748 fOptionConflictView->Invalidate();
750 if (commandIcon != fCommandConflictView->Icon())
751 fCommandConflictView->Invalidate();
755 // return a mask marking which keys are duplicates of each other for
756 // validation. Shift = 0, Control = 1, Option = 2, Command = 3
757 uint32
758 ModifierKeysWindow::_DuplicateKeys()
760 uint32 duplicateMask = 0;
762 for (int32 testKey = MENU_ITEM_SHIFT; testKey <= MENU_ITEM_COMMAND;
763 testKey++) {
764 uint32 testLeft = 0;
765 uint32 testRight = 0;
767 switch (testKey) {
768 case MENU_ITEM_SHIFT:
769 testLeft = fCurrentMap->left_shift_key;
770 testRight = fCurrentMap->right_shift_key;
771 break;
773 case MENU_ITEM_CONTROL:
774 testLeft = fCurrentMap->left_control_key;
775 testRight = fCurrentMap->right_control_key;
776 break;
778 case MENU_ITEM_OPTION:
779 testLeft = fCurrentMap->left_option_key;
780 testRight = fCurrentMap->right_option_key;
781 break;
783 case MENU_ITEM_COMMAND:
784 testLeft = fCurrentMap->left_command_key;
785 testRight = fCurrentMap->right_command_key;
786 break;
789 if (testLeft == 0 && testRight == 0)
790 continue;
792 for (int32 key = MENU_ITEM_SHIFT; key <= MENU_ITEM_COMMAND; key++) {
793 if (key == testKey) {
794 // skip over yourself
795 continue;
798 uint32 left = 0;
799 uint32 right = 0;
801 switch (key) {
802 case MENU_ITEM_SHIFT:
803 left = fCurrentMap->left_shift_key;
804 right = fCurrentMap->right_shift_key;
805 break;
807 case MENU_ITEM_CONTROL:
808 left = fCurrentMap->left_control_key;
809 right = fCurrentMap->right_control_key;
810 break;
812 case MENU_ITEM_OPTION:
813 left = fCurrentMap->left_option_key;
814 right = fCurrentMap->right_option_key;
815 break;
817 case MENU_ITEM_COMMAND:
818 left = fCurrentMap->left_command_key;
819 right = fCurrentMap->right_command_key;
820 break;
823 if (left == 0 && right == 0)
824 continue;
826 if (left == testLeft || right == testRight) {
827 duplicateMask |= 1 << testKey;
828 duplicateMask |= 1 << key;
833 return duplicateMask;
837 void
838 ModifierKeysWindow::_HideShowIcons()
840 if (fShiftConflictView->Icon() == NULL) {
841 while (!fShiftConflictView->IsHidden())
842 fShiftConflictView->Hide();
843 } else {
844 while (fShiftConflictView->IsHidden())
845 fShiftConflictView->Show();
848 if (fControlConflictView->Icon() == NULL) {
849 while (!fControlConflictView->IsHidden())
850 fControlConflictView->Hide();
851 } else {
852 while (fControlConflictView->IsHidden())
853 fControlConflictView->Show();
856 if (fOptionConflictView->Icon() == NULL) {
857 while (!fOptionConflictView->IsHidden())
858 fOptionConflictView->Hide();
859 } else {
860 while (fOptionConflictView->IsHidden())
861 fOptionConflictView->Show();
864 if (fCommandConflictView->Icon() == NULL) {
865 while (!fCommandConflictView->IsHidden())
866 fCommandConflictView->Hide();
867 } else {
868 while (fCommandConflictView->IsHidden())
869 fCommandConflictView->Show();