1 /* 2 * Copyright 2004-2008 Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Sandor Vroemisse 7 * Jérôme Duval 8 * Alexandre Deckner, alex@zappotek.com 9 */ 10 11 #include <Alert.h> 12 #include <Application.h> 13 #include <Bitmap.h> 14 #include <Box.h> 15 #include <Button.h> 16 #include <Clipboard.h> 17 #include <Debug.h> 18 #include <Directory.h> 19 #include <FindDirectory.h> 20 #include <GraphicsDefs.h> 21 #include <ListView.h> 22 #include <MenuItem.h> 23 #include <Path.h> 24 #include <Region.h> 25 #include <ScrollView.h> 26 #include <StringView.h> 27 #include <TextView.h> 28 #include <View.h> 29 #include <string.h> 30 #include "KeymapWindow.h" 31 #include "KeymapListItem.h" 32 #include "KeymapApplication.h" 33 34 static const uint32 kMsgMenuFileOpen = 'mMFO'; 35 static const uint32 kMsgMenuFileSave = 'mMFS'; 36 static const uint32 kMsgMenuFileSaveAs = 'mMFA'; 37 static const uint32 kMsgMenuEditUndo = 'mMEU'; 38 static const uint32 kMsgMenuEditCut = 'mMEX'; 39 static const uint32 kMsgMenuEditCopy = 'mMEC'; 40 static const uint32 kMsgMenuEditPaste = 'mMEV'; 41 static const uint32 kMsgMenuEditClear = 'mMEL'; 42 static const uint32 kMsgMenuEditSelectAll = 'mMEA'; 43 static const uint32 kMsgMenuFontChanged = 'mMFC'; 44 static const uint32 kMsgSystemMapSelected = 'SmST'; 45 static const uint32 kMsgUserMapSelected = 'UmST'; 46 static const uint32 kMsgUseKeymap = 'UkyM'; 47 static const uint32 kMsgRevertKeymap = 'Rvrt'; 48 49 KeymapWindow::KeymapWindow() 50 : BWindow(BRect(80, 25, 750, 280), "Keymap", B_TITLED_WINDOW, 51 B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS ) 52 { 53 fFirstTime = true; 54 55 // Add the menu bar 56 BMenuBar *menubar = AddMenuBar(); 57 58 // The view to hold all but the menu bar 59 BRect bounds = Bounds(); 60 bounds.top = menubar->Bounds().bottom + 1; 61 BBox *placeholderView = new BBox(bounds, "placeholderView", 62 B_FOLLOW_ALL); 63 placeholderView->SetBorder(B_NO_BORDER); 64 AddChild(placeholderView); 65 66 // Create the Maps box and contents 67 AddMaps(placeholderView); 68 69 fMapView = new MapView(BRect(205, 15, 655, 189), "mapView", &fCurrentMap); 70 placeholderView->AddChild(fMapView); 71 72 BMenuItem *item = fFontMenu->FindMarked(); 73 if (item) { 74 fMapView->SetFontFamily(item->Label()); 75 } 76 77 // The 'Use' button 78 fUseButton = new BButton(BRect(582, 200, 655, 220), "useButton", "Use", 79 new BMessage(kMsgUseKeymap)); 80 placeholderView->AddChild(fUseButton); 81 82 // The 'Revert' button 83 fRevertButton = new BButton(BRect(497, 200, 570, 220), "revertButton", 84 "Revert", new BMessage(kMsgRevertKeymap)); 85 placeholderView->AddChild(fRevertButton); 86 UpdateButtons(); 87 88 BPath path; 89 find_directory(B_USER_SETTINGS_DIRECTORY, &path); 90 path.Append("Keymap"); 91 92 entry_ref ref; 93 get_ref_for_path(path.Path(), &ref); 94 95 BDirectory userKeymapsDir(&ref); 96 if (userKeymapsDir.InitCheck() != B_OK) { 97 create_directory(path.Path(), S_IRWXU | S_IRWXG | S_IRWXO); 98 } 99 100 BMessenger messenger(this); 101 fOpenPanel = new BFilePanel(B_OPEN_PANEL, &messenger, &ref, 102 B_FILE_NODE, false, NULL); 103 fSavePanel = new BFilePanel(B_SAVE_PANEL, &messenger, &ref, 104 B_FILE_NODE, false, NULL); 105 } 106 107 108 KeymapWindow::~KeymapWindow(void) 109 { 110 delete fOpenPanel; 111 delete fSavePanel; 112 } 113 114 115 BMenuBar * 116 KeymapWindow::AddMenuBar() 117 { 118 BRect bounds; 119 BMenu *menu; 120 BMenuItem *currentItem; 121 BMenuBar *menubar; 122 123 bounds = Bounds(); 124 menubar = new BMenuBar(bounds, "menubar"); 125 AddChild(menubar); 126 127 // Create the File menu 128 menu = new BMenu("File"); 129 menu->AddItem(new BMenuItem("Open" B_UTF8_ELLIPSIS, 130 new BMessage(kMsgMenuFileOpen), 'O')); 131 menu->AddSeparatorItem(); 132 currentItem = new BMenuItem("Save", 133 new BMessage(kMsgMenuFileSave), 'S'); 134 currentItem->SetEnabled(false); 135 menu->AddItem(currentItem); 136 menu->AddItem(new BMenuItem("Save As" B_UTF8_ELLIPSIS, 137 new BMessage(kMsgMenuFileSaveAs))); 138 menu->AddSeparatorItem(); 139 menu->AddItem(new BMenuItem("Quit", 140 new BMessage(B_QUIT_REQUESTED), 'Q')); 141 menubar->AddItem(menu); 142 143 // Create the Edit menu 144 menu = new BMenu("Edit"); 145 currentItem = new BMenuItem("Undo", 146 new BMessage(kMsgMenuEditUndo), 'Z'); 147 currentItem->SetEnabled(false); 148 menu->AddItem(currentItem); 149 menu->AddSeparatorItem(); 150 menu->AddItem(new BMenuItem( "Cut", 151 new BMessage(kMsgMenuEditCut), 'X')); 152 menu->AddItem(new BMenuItem( "Copy", 153 new BMessage(kMsgMenuEditCopy), 'C')); 154 menu->AddItem(new BMenuItem( "Paste", 155 new BMessage(kMsgMenuEditPaste), 'V')); 156 menu->AddItem(new BMenuItem( "Clear", 157 new BMessage(kMsgMenuEditClear))); 158 menu->AddSeparatorItem(); 159 menu->AddItem(new BMenuItem( "Select All", 160 new BMessage(kMsgMenuEditSelectAll), 'A')); 161 menubar->AddItem(menu); 162 163 // Create the Font menu 164 fFontMenu = new BMenu("Font"); 165 fFontMenu->SetRadioMode(true); 166 int32 numFamilies = count_font_families(); 167 font_family family, current_family; 168 font_style current_style; 169 uint32 flags; 170 171 be_plain_font->GetFamilyAndStyle(¤t_family, ¤t_style); 172 173 for (int32 i = 0; i < numFamilies; i++ ) 174 if (get_font_family(i, &family, &flags) == B_OK) { 175 BMenuItem *item = 176 new BMenuItem(family, new BMessage(kMsgMenuFontChanged)); 177 fFontMenu->AddItem(item); 178 if (strcmp(family, current_family) == 0) 179 item->SetMarked(true); 180 } 181 menubar->AddItem(fFontMenu); 182 183 return menubar; 184 } 185 186 187 void 188 KeymapWindow::AddMaps(BView *placeholderView) 189 { 190 // The System list 191 BStringView *systemLabel = new BStringView(BRect(13, 5, 143, 28), "system", "System:"); 192 placeholderView->AddChild(systemLabel); 193 194 BRect bounds = BRect(13, 27, 173, 130); 195 fSystemListView = new BListView(bounds, "systemList"); 196 197 placeholderView->AddChild(new BScrollView("systemScrollList", fSystemListView, 198 B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true)); 199 fSystemListView->SetSelectionMessage(new BMessage(kMsgSystemMapSelected)); 200 201 // The User list 202 BStringView *userLabel = new BStringView(BRect(13, 135, 143, 153), "user", "User:"); 203 placeholderView->AddChild(userLabel); 204 205 bounds = BRect(13, 155, 173, 225); 206 fUserListView = new BListView(bounds, "userList"); 207 // '(Current)' 208 KeymapListItem *currentKeymapItem = static_cast<KeymapListItem*>(fUserListView->FirstItem()); 209 if (currentKeymapItem != NULL) 210 fUserListView->AddItem(currentKeymapItem); 211 // Saved keymaps 212 placeholderView->AddChild(new BScrollView("userScrollList", fUserListView, 213 B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true)); 214 fUserListView->SetSelectionMessage(new BMessage(kMsgUserMapSelected)); 215 216 FillSystemMaps(); 217 FillUserMaps(); 218 219 // try and find the current map name in the two list views (if the name was read at all) 220 if (!SelectCurrentMap(fSystemListView)) 221 if (!SelectCurrentMap(fUserListView)) 222 fUserListView->Select(0L); 223 } 224 225 226 bool 227 KeymapWindow::QuitRequested() 228 { 229 be_app->PostMessage(B_QUIT_REQUESTED); 230 return true; 231 } 232 233 234 void 235 KeymapWindow::MessageReceived(BMessage* message) 236 { 237 switch(message->what) { 238 case B_SIMPLE_DATA: 239 case B_REFS_RECEIVED: 240 { 241 entry_ref ref; 242 int32 i = 0; 243 while (message->FindRef("refs", i++, &ref) == B_OK) { 244 fCurrentMap.Load(ref); 245 } 246 fMapView->Invalidate(); 247 fSystemListView->DeselectAll(); 248 fUserListView->DeselectAll(); 249 } 250 break; 251 case B_SAVE_REQUESTED: 252 { 253 entry_ref ref; 254 const char *name; 255 if ((message->FindRef("directory", &ref) == B_OK) 256 && (message->FindString("name", &name) == B_OK)) { 257 258 BDirectory directory(&ref); 259 BEntry entry(&directory, name); 260 entry.GetRef(&ref); 261 fCurrentMap.Save(ref); 262 263 FillUserMaps(); 264 } 265 } 266 break; 267 case kMsgMenuFileOpen: 268 fOpenPanel->Show(); 269 break; 270 case kMsgMenuFileSave: 271 break; 272 case kMsgMenuFileSaveAs: 273 fSavePanel->Show(); 274 break; 275 case kMsgMenuEditUndo: 276 case kMsgMenuEditCut: 277 case kMsgMenuEditCopy: 278 case kMsgMenuEditPaste: 279 case kMsgMenuEditClear: 280 case kMsgMenuEditSelectAll: 281 fMapView->MessageReceived(message); 282 break; 283 case kMsgMenuFontChanged: 284 { 285 BMenuItem *item = fFontMenu->FindMarked(); 286 if (item) { 287 fMapView->SetFontFamily(item->Label()); 288 fMapView->Invalidate(); 289 } 290 } 291 break; 292 case kMsgSystemMapSelected: 293 { 294 KeymapListItem *keymapListItem = 295 static_cast<KeymapListItem*>(fSystemListView->ItemAt(fSystemListView->CurrentSelection())); 296 if (keymapListItem) { 297 fCurrentMap.Load(keymapListItem->KeymapEntry()); 298 299 if (fFirstTime) { 300 fPreviousMap.Load(keymapListItem->KeymapEntry()); 301 fAppliedMap.Load(keymapListItem->KeymapEntry()); 302 fFirstTime = false; 303 } 304 305 fMapView->Invalidate(); 306 307 // Deselect item in other BListView 308 fUserListView->DeselectAll(); 309 UpdateButtons(); 310 } 311 } 312 break; 313 case kMsgUserMapSelected: 314 { 315 KeymapListItem *keymapListItem = 316 static_cast<KeymapListItem*>(fUserListView->ItemAt(fUserListView->CurrentSelection())); 317 if (keymapListItem) { 318 fCurrentMap.Load(keymapListItem->KeymapEntry()); 319 320 if (fFirstTime) { 321 fPreviousMap.Load(keymapListItem->KeymapEntry()); 322 fAppliedMap.Load(keymapListItem->KeymapEntry()); 323 fFirstTime = false; 324 } 325 326 fMapView->Invalidate(); 327 328 // Deselect item in other BListView 329 fSystemListView->DeselectAll(); 330 UpdateButtons(); 331 } 332 } 333 break; 334 case kMsgUseKeymap: 335 UseKeymap(); 336 UpdateButtons(); 337 break; 338 case kMsgRevertKeymap: 339 RevertKeymap(); 340 UpdateButtons(); 341 break; 342 default: 343 BWindow::MessageReceived(message); 344 break; 345 } 346 } 347 348 349 void 350 KeymapWindow::UpdateButtons() 351 { 352 fUseButton->SetEnabled(!fCurrentMap.Equals(fAppliedMap)); 353 fRevertButton->SetEnabled(!fCurrentMap.Equals(fPreviousMap)); 354 } 355 356 357 void 358 KeymapWindow::RevertKeymap() 359 { 360 //saves previous map to the Key_map file 361 362 BPath path; 363 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path)!=B_OK) 364 return; 365 366 path.Append("Key_map"); 367 368 entry_ref ref; 369 get_ref_for_path(path.Path(), &ref); 370 371 status_t err; 372 if ((err = fPreviousMap.Save(ref)) != B_OK) { 373 printf("error when saving : %s", strerror(err)); 374 return; 375 } 376 fPreviousMap.Use(); 377 fAppliedMap.Load(ref); 378 379 fCurrentMapName = GetActiveKeymapName(); 380 381 if (!SelectCurrentMap(fSystemListView)) 382 if (!SelectCurrentMap(fUserListView)) 383 fUserListView->Select(0L); 384 } 385 386 387 void 388 KeymapWindow::UseKeymap() 389 { 390 BPath path; 391 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 392 return; 393 394 path.Append("Key_map"); 395 396 entry_ref ref; 397 get_ref_for_path(path.Path(), &ref); 398 399 status_t err; 400 if ((err = fCurrentMap.Save(ref)) != B_OK) { 401 printf("error when saving : %s", strerror(err)); 402 return; 403 } 404 fCurrentMap.Use(); 405 fAppliedMap.Load(ref); 406 407 fCurrentMapName = GetActiveKeymapName(); 408 } 409 410 411 void 412 KeymapWindow::FillSystemMaps() 413 { 414 BListItem *item; 415 while ((item = fSystemListView->RemoveItem(static_cast<int32>(0)))) 416 delete item; 417 418 BPath path; 419 if (find_directory(B_BEOS_ETC_DIRECTORY, &path) != B_OK) 420 return; 421 422 path.Append("Keymap"); 423 424 BDirectory directory; 425 entry_ref ref; 426 427 if (directory.SetTo(path.Path()) == B_OK) 428 while( directory.GetNextRef(&ref) == B_OK ) { 429 fSystemListView->AddItem(new KeymapListItem(ref)); 430 } 431 } 432 433 434 void 435 KeymapWindow::FillUserMaps() 436 { 437 BListItem *item; 438 while ((item = fUserListView->RemoveItem(static_cast<int32>(0)))) 439 delete item; 440 441 BPath path; 442 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 443 return; 444 445 path.Append("Key_map"); 446 447 entry_ref ref; 448 get_ref_for_path(path.Path(), &ref); 449 450 fUserListView->AddItem(new KeymapListItem(ref, "(Current)")); 451 452 fCurrentMapName = GetActiveKeymapName(); 453 454 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 455 return; 456 457 path.Append("Keymap"); 458 459 BDirectory directory; 460 461 if (directory.SetTo(path.Path()) == B_OK) 462 while( directory.GetNextRef(&ref) == B_OK ) { 463 fUserListView->AddItem(new KeymapListItem(ref)); 464 } 465 } 466 467 468 BString 469 KeymapWindow::GetActiveKeymapName() 470 { 471 BString mapName = "(Current)"; //safe default 472 473 BPath path; 474 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 475 return mapName; 476 477 path.Append("Key_map"); 478 479 entry_ref ref; 480 get_ref_for_path(path.Path(), &ref); 481 BNode node(&ref); 482 483 if (node.InitCheck() == B_OK) 484 node.ReadAttrString("keymap:name", &mapName); 485 486 return mapName; 487 } 488 489 490 bool 491 KeymapWindow::SelectCurrentMap(BListView *view) 492 { 493 bool found = false; 494 if (fCurrentMapName.Length() > 0) { 495 for (int32 i = 0; i < view->CountItems(); i++) { 496 BStringItem *current = dynamic_cast<BStringItem *>(view->ItemAt(i)); 497 if (current && (fCurrentMapName == current->Text())) { 498 found = true; 499 view->Select(i); 500 view->ScrollToSelection(); 501 break; 502 } 503 } 504 } 505 return found; 506 } 507 508 509 MapView::MapView(BRect rect, const char *name, Keymap* keymap) 510 : BControl(rect, name, NULL, NULL, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW), 511 fCurrentFont(*be_plain_font), 512 fCurrentMap(keymap), 513 fCurrentMouseKey(0) 514 { 515 // TODO: Properly handle font sensitivity in drawing the keys. 516 // This at least prevents the app from looking horrible until the font sensitivity for this app 517 // can be done the Right Way. 518 if (fCurrentFont.Size() > 14) 519 fCurrentFont.SetSize(14); 520 521 BRect frameRect = BRect(14, 16, Bounds().right - 12, 30); 522 BRect textRect = frameRect; 523 textRect.OffsetTo(B_ORIGIN); 524 textRect.InsetBy(1, 1); 525 fTextView = new KeymapTextView(frameRect, "testzone", textRect, 526 B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_FRAME_EVENTS); 527 fTextView->MakeEditable(true); 528 fTextView->MakeSelectable(true); 529 530 AddChild(fTextView); 531 532 fBitmap = new BBitmap(Bounds(), B_RGB32, true, false); 533 fOffscreenView = new BView(Bounds(), "off_view", 0, 0); 534 535 fBitmap->Lock(); 536 fBitmap->AddChild(fOffscreenView); 537 fBitmap->Unlock(); 538 539 for (uint32 j = 0; j < 128; j++) 540 fKeysToDraw[j] = false; 541 542 BRect keyRect = BRect(11, 50, 29, 68); 543 uint32 i = 1; 544 fKeysRect[i] = keyRect; 545 fKeysToDraw[i] = true; 546 547 // Fx keys 548 i++; 549 keyRect.OffsetBySelf(36, 0); 550 fKeysRect[i] = keyRect; 551 fKeysToDraw[i] = true; 552 i++; 553 keyRect.OffsetBySelf(18, 0); 554 fKeysRect[i] = keyRect; 555 fKeysToDraw[i] = true; 556 i++; 557 keyRect.OffsetBySelf(18, 0); 558 fKeysRect[i] = keyRect; 559 fKeysToDraw[i] = true; 560 i++; 561 keyRect.OffsetBySelf(18, 0); 562 fKeysRect[i] = keyRect; 563 fKeysToDraw[i] = true; 564 565 i++; 566 keyRect.OffsetBySelf(27, 0); 567 fKeysRect[i] = keyRect; 568 fKeysToDraw[i] = true; 569 i++; 570 keyRect.OffsetBySelf(18, 0); 571 fKeysRect[i] = keyRect; 572 fKeysToDraw[i] = true; 573 i++; 574 keyRect.OffsetBySelf(18, 0); 575 fKeysRect[i] = keyRect; 576 fKeysToDraw[i] = true; 577 i++; 578 keyRect.OffsetBySelf(18, 0); 579 fKeysRect[i] = keyRect; 580 fKeysToDraw[i] = true; 581 582 i++; 583 keyRect.OffsetBySelf(27, 0); 584 fKeysRect[i] = keyRect; 585 fKeysToDraw[i] = true; 586 i++; 587 keyRect.OffsetBySelf(18, 0); 588 fKeysRect[i] = keyRect; 589 fKeysToDraw[i] = true; 590 i++; 591 keyRect.OffsetBySelf(18, 0); 592 fKeysRect[i] = keyRect; 593 fKeysToDraw[i] = true; 594 i++; 595 keyRect.OffsetBySelf(18, 0); 596 fKeysRect[i] = keyRect; 597 fKeysToDraw[i] = true; 598 599 // Pause, PrintScreen, ... 600 i++; 601 keyRect.OffsetBySelf(35, 0); 602 fKeysRect[i] = keyRect; 603 fKeysToDraw[i] = true; 604 i++; 605 keyRect.OffsetBySelf(18, 0); 606 fKeysRect[i] = keyRect; 607 fKeysToDraw[i] = true; 608 i++; 609 keyRect.OffsetBySelf(18, 0); 610 fKeysRect[i] = keyRect; 611 fKeysToDraw[i] = true; 612 613 // 1st line : numbers and backspace 614 i++; 615 keyRect = BRect(11, 78, 29, 96); 616 fKeysRect[i] = keyRect; 617 fKeysToDraw[i] = true; 618 i++; 619 keyRect.OffsetBySelf(18, 0); 620 fKeysRect[i] = keyRect; 621 fKeysToDraw[i] = true; 622 i++; 623 keyRect.OffsetBySelf(18, 0); 624 fKeysRect[i] = keyRect; 625 fKeysToDraw[i] = true; 626 i++; 627 keyRect.OffsetBySelf(18, 0); 628 fKeysRect[i] = keyRect; 629 fKeysToDraw[i] = true; 630 i++; 631 keyRect.OffsetBySelf(18, 0); 632 fKeysRect[i] = keyRect; 633 fKeysToDraw[i] = true; 634 i++; 635 keyRect.OffsetBySelf(18, 0); 636 fKeysRect[i] = keyRect; 637 fKeysToDraw[i] = true; 638 i++; 639 keyRect.OffsetBySelf(18, 0); 640 fKeysRect[i] = keyRect; 641 fKeysToDraw[i] = true; 642 i++; 643 keyRect.OffsetBySelf(18, 0); 644 fKeysRect[i] = keyRect; 645 fKeysToDraw[i] = true; 646 i++; 647 keyRect.OffsetBySelf(18, 0); 648 fKeysRect[i] = keyRect; 649 fKeysToDraw[i] = true; 650 i++; 651 keyRect.OffsetBySelf(18, 0); 652 fKeysRect[i] = keyRect; 653 fKeysToDraw[i] = true; 654 i++; 655 keyRect.OffsetBySelf(18, 0); 656 fKeysRect[i] = keyRect; 657 fKeysToDraw[i] = true; 658 i++; 659 keyRect.OffsetBySelf(18, 0); 660 fKeysRect[i] = keyRect; 661 fKeysToDraw[i] = true; 662 i++; 663 keyRect.OffsetBySelf(18, 0); 664 fKeysRect[i] = keyRect; 665 fKeysToDraw[i] = true; 666 i++; 667 keyRect.OffsetBySelf(18, 0); 668 keyRect.right += 18; 669 fKeysRect[i] = keyRect; 670 fKeysToDraw[i] = true; 671 keyRect.left += 18; 672 673 // Insert, pg up ... 674 i++; 675 keyRect.OffsetBySelf(35, 0); 676 fKeysRect[i] = keyRect; 677 fKeysToDraw[i] = true; 678 i++; 679 keyRect.OffsetBySelf(18, 0); 680 fKeysRect[i] = keyRect; 681 fKeysToDraw[i] = true; 682 i++; 683 keyRect.OffsetBySelf(18, 0); 684 fKeysRect[i] = keyRect; 685 fKeysToDraw[i] = true; 686 687 // 2nd line : tab and azerty ... 688 i = 0x26; 689 keyRect = BRect(11, 96, 38, 114); 690 fKeysRect[i] = keyRect; 691 fKeysToDraw[i] = true; 692 i++; 693 keyRect.OffsetBySelf(27, 0); 694 keyRect.right -= 9; 695 fKeysRect[i] = keyRect; 696 fKeysToDraw[i] = true; 697 i++; 698 keyRect.OffsetBySelf(18, 0); 699 fKeysRect[i] = keyRect; 700 fKeysToDraw[i] = true; 701 i++; 702 keyRect.OffsetBySelf(18, 0); 703 fKeysRect[i] = keyRect; 704 fKeysToDraw[i] = true; 705 i++; 706 keyRect.OffsetBySelf(18, 0); 707 fKeysRect[i] = keyRect; 708 fKeysToDraw[i] = true; 709 i++; 710 keyRect.OffsetBySelf(18, 0); 711 fKeysRect[i] = keyRect; 712 fKeysToDraw[i] = true; 713 i++; 714 keyRect.OffsetBySelf(18, 0); 715 fKeysRect[i] = keyRect; 716 fKeysToDraw[i] = true; 717 i++; 718 keyRect.OffsetBySelf(18, 0); 719 fKeysRect[i] = keyRect; 720 fKeysToDraw[i] = true; 721 i++; 722 keyRect.OffsetBySelf(18, 0); 723 fKeysRect[i] = keyRect; 724 fKeysToDraw[i] = true; 725 i++; 726 keyRect.OffsetBySelf(18, 0); 727 fKeysRect[i] = keyRect; 728 fKeysToDraw[i] = true; 729 i++; 730 keyRect.OffsetBySelf(18, 0); 731 fKeysRect[i] = keyRect; 732 fKeysToDraw[i] = true; 733 i++; 734 keyRect.OffsetBySelf(18, 0); 735 fKeysRect[i] = keyRect; 736 fKeysToDraw[i] = true; 737 i++; 738 keyRect.OffsetBySelf(18, 0); 739 fKeysRect[i] = keyRect; 740 fKeysToDraw[i] = true; 741 i++; 742 keyRect.OffsetBySelf(18, 0); 743 keyRect.right += 9; 744 fKeysRect[i] = keyRect; 745 fKeysToDraw[i] = true; 746 keyRect.left += 9; 747 748 // Suppr, pg down ... 749 i++; 750 keyRect.OffsetBySelf(35, 0); 751 fKeysRect[i] = keyRect; 752 fKeysToDraw[i] = true; 753 i++; 754 keyRect.OffsetBySelf(18, 0); 755 fKeysRect[i] = keyRect; 756 fKeysToDraw[i] = true; 757 i++; 758 keyRect.OffsetBySelf(18, 0); 759 fKeysRect[i] = keyRect; 760 fKeysToDraw[i] = true; 761 762 // 3rd line : caps and qsdfg ... 763 i = 0x3b; 764 keyRect = BRect(11, 114, 47, 132); 765 fKeysRect[i] = keyRect; 766 fKeysToDraw[i] = true; 767 i++; 768 keyRect.OffsetBySelf(36, 0); 769 keyRect.right -= 18; 770 fKeysRect[i] = keyRect; 771 fKeysToDraw[i] = true; 772 i++; 773 keyRect.OffsetBySelf(18, 0); 774 fKeysRect[i] = keyRect; 775 fKeysToDraw[i] = true; 776 i++; 777 keyRect.OffsetBySelf(18, 0); 778 fKeysRect[i] = keyRect; 779 fKeysToDraw[i] = true; 780 i++; 781 keyRect.OffsetBySelf(18, 0); 782 fKeysRect[i] = keyRect; 783 fKeysToDraw[i] = true; 784 i++; 785 keyRect.OffsetBySelf(18, 0); 786 fKeysRect[i] = keyRect; 787 fKeysToDraw[i] = true; 788 i++; 789 keyRect.OffsetBySelf(18, 0); 790 fKeysRect[i] = keyRect; 791 fKeysToDraw[i] = true; 792 i++; 793 keyRect.OffsetBySelf(18, 0); 794 fKeysRect[i] = keyRect; 795 fKeysToDraw[i] = true; 796 i++; 797 keyRect.OffsetBySelf(18, 0); 798 fKeysRect[i] = keyRect; 799 fKeysToDraw[i] = true; 800 i++; 801 keyRect.OffsetBySelf(18, 0); 802 fKeysRect[i] = keyRect; 803 fKeysToDraw[i] = true; 804 i++; 805 keyRect.OffsetBySelf(18, 0); 806 fKeysRect[i] = keyRect; 807 fKeysToDraw[i] = true; 808 i++; 809 keyRect.OffsetBySelf(18, 0); 810 fKeysRect[i] = keyRect; 811 fKeysToDraw[i] = true; 812 i++; 813 keyRect.OffsetBySelf(18, 0); 814 keyRect.right += 18; 815 fKeysRect[i] = keyRect; 816 fKeysToDraw[i] = true; 817 keyRect.left += 18; 818 819 // 4th line : shift and wxcv ... 820 i = 0x4b; 821 keyRect = BRect(11, 132, 56, 150); 822 fKeysRect[i] = keyRect; 823 fKeysToDraw[i] = true; 824 i++; 825 keyRect.OffsetBySelf(45, 0); 826 keyRect.right -= 27; 827 fKeysRect[i] = keyRect; 828 fKeysToDraw[i] = true; 829 i++; 830 keyRect.OffsetBySelf(18, 0); 831 fKeysRect[i] = keyRect; 832 fKeysToDraw[i] = true; 833 i++; 834 keyRect.OffsetBySelf(18, 0); 835 fKeysRect[i] = keyRect; 836 fKeysToDraw[i] = true; 837 i++; 838 keyRect.OffsetBySelf(18, 0); 839 fKeysRect[i] = keyRect; 840 fKeysToDraw[i] = true; 841 i++; 842 keyRect.OffsetBySelf(18, 0); 843 fKeysRect[i] = keyRect; 844 fKeysToDraw[i] = true; 845 i++; 846 keyRect.OffsetBySelf(18, 0); 847 fKeysRect[i] = keyRect; 848 fKeysToDraw[i] = true; 849 i++; 850 keyRect.OffsetBySelf(18, 0); 851 fKeysRect[i] = keyRect; 852 fKeysToDraw[i] = true; 853 i++; 854 keyRect.OffsetBySelf(18, 0); 855 fKeysRect[i] = keyRect; 856 fKeysToDraw[i] = true; 857 i++; 858 keyRect.OffsetBySelf(18, 0); 859 fKeysRect[i] = keyRect; 860 fKeysToDraw[i] = true; 861 i++; 862 keyRect.OffsetBySelf(18, 0); 863 fKeysRect[i] = keyRect; 864 fKeysToDraw[i] = true; 865 i++; 866 keyRect.OffsetBySelf(18, 0); 867 keyRect.right += 27; 868 fKeysRect[i] = keyRect; 869 fKeysToDraw[i] = true; 870 keyRect.left += 27; 871 872 //5th line : Ctrl, Alt, Space ... 873 i = 0x5c; 874 keyRect = BRect(11, 150, 38, 168); 875 fKeysRect[i] = keyRect; 876 fKeysToDraw[i] = true; 877 i++; 878 keyRect.OffsetBySelf(27, 0); 879 keyRect.OffsetBySelf(26, 0); 880 fKeysRect[i] = keyRect; 881 fKeysToDraw[i] = true; 882 i++; 883 keyRect.OffsetBySelf(27, 0); 884 keyRect.right += 92; 885 fKeysRect[i] = keyRect; 886 fKeysToDraw[i] = true; 887 i++; 888 keyRect.right -= 92; 889 keyRect.OffsetBySelf(92, 0); 890 keyRect.OffsetBySelf(27, 0); 891 fKeysRect[i] = keyRect; 892 fKeysToDraw[i] = true; 893 i++; 894 keyRect.OffsetBySelf(26, 0); 895 keyRect.OffsetBySelf(18, 0); 896 fKeysRect[i] = keyRect; 897 fKeysToDraw[i] = true; 898 899 // Arrows 900 i++; 901 keyRect = BRect(298, 150, 316, 168); 902 fKeysRect[i] = keyRect; 903 fKeysToDraw[i] = true; 904 i++; 905 keyRect.OffsetBySelf(18, 0); 906 fKeysRect[i] = keyRect; 907 fKeysToDraw[i] = true; 908 i++; 909 keyRect.OffsetBySelf(18, 0); 910 fKeysRect[i] = keyRect; 911 fKeysToDraw[i] = true; 912 i = 0x57; 913 keyRect.OffsetBySelf(-18, -18); 914 fKeysRect[i] = keyRect; 915 fKeysToDraw[i] = true; 916 917 // numkeys 918 i = 0x22; 919 keyRect = BRect(369, 78, 387, 96); 920 fKeysRect[i] = keyRect; 921 fKeysToDraw[i] = true; 922 i++; 923 keyRect.OffsetBySelf(18, 0); 924 fKeysRect[i] = keyRect; 925 fKeysToDraw[i] = true; 926 i++; 927 keyRect.OffsetBySelf(18, 0); 928 fKeysRect[i] = keyRect; 929 fKeysToDraw[i] = true; 930 i++; 931 keyRect.OffsetBySelf(18, 0); 932 fKeysRect[i] = keyRect; 933 fKeysToDraw[i] = true; 934 i = 0x37; 935 keyRect.OffsetBySelf(-54, 18); 936 fKeysRect[i] = keyRect; 937 fKeysToDraw[i] = true; 938 i++; 939 keyRect.OffsetBySelf(18, 0); 940 fKeysRect[i] = keyRect; 941 fKeysToDraw[i] = true; 942 i++; 943 keyRect.OffsetBySelf(18, 0); 944 fKeysRect[i] = keyRect; 945 fKeysToDraw[i] = true; 946 i++; 947 keyRect.OffsetBySelf(18, 0); 948 keyRect.bottom += 18; 949 fKeysRect[i] = keyRect; 950 fKeysToDraw[i] = true; 951 i = 0x48; 952 keyRect.bottom -= 18; 953 keyRect.OffsetBySelf(-54, 18); 954 fKeysRect[i] = keyRect; 955 fKeysToDraw[i] = true; 956 i++; 957 keyRect.OffsetBySelf(18, 0); 958 fKeysRect[i] = keyRect; 959 fKeysToDraw[i] = true; 960 i++; 961 keyRect.OffsetBySelf(18, 0); 962 fKeysRect[i] = keyRect; 963 fKeysToDraw[i] = true; 964 i = 0x58; 965 keyRect.OffsetBySelf(-36, 18); 966 fKeysRect[i] = keyRect; 967 fKeysToDraw[i] = true; 968 i++; 969 keyRect.OffsetBySelf(18, 0); 970 fKeysRect[i] = keyRect; 971 fKeysToDraw[i] = true; 972 i++; 973 keyRect.OffsetBySelf(18, 0); 974 fKeysRect[i] = keyRect; 975 fKeysToDraw[i] = true; 976 i++; 977 keyRect.OffsetBySelf(18, 0); 978 keyRect.bottom += 18; 979 fKeysRect[i] = keyRect; 980 fKeysToDraw[i] = true; 981 i = 0x64; 982 keyRect.bottom -= 18; 983 keyRect.OffsetBySelf(-54, 18); 984 keyRect.right += 18; 985 fKeysRect[i] = keyRect; 986 fKeysToDraw[i] = true; 987 i++; 988 keyRect.right -= 18; 989 keyRect.OffsetBySelf(36, 0); 990 fKeysRect[i] = keyRect; 991 fKeysToDraw[i] = true; 992 993 for (uint32 j = 0; j < 128; j++) 994 fKeysVertical[j] = false; 995 996 fKeysVertical[0x5e] = true; 997 998 fActiveDeadKey = 0; 999 1000 for (int8 j = 0; j < 16; j++) 1001 fOldKeyInfo.key_states[j] = 0; 1002 fOldKeyInfo.modifiers = 0; 1003 } 1004 1005 1006 MapView::~MapView() 1007 { 1008 delete fBitmap; 1009 } 1010 1011 1012 void 1013 MapView::_InitOffscreen() 1014 { 1015 if (fBitmap->Lock()) { 1016 _DrawBackground(); 1017 fOffscreenView->Sync(); 1018 fBitmap->Unlock(); 1019 } 1020 } 1021 1022 1023 void 1024 MapView::AttachedToWindow() 1025 { 1026 BControl::AttachedToWindow(); 1027 1028 SetEventMask(B_KEYBOARD_EVENTS, 0); 1029 SetViewColor(B_TRANSPARENT_COLOR); 1030 fTextView->SetViewColor(255, 255, 255); 1031 _InitOffscreen(); 1032 } 1033 1034 1035 void 1036 MapView::_DrawBackground(){ 1037 BRect r = fOffscreenView->Bounds(); 1038 fOffscreenView->SetHighColor(0, 0, 0); 1039 fOffscreenView->StrokeRect(r); 1040 1041 r.InsetBySelf(1, 1); 1042 fOffscreenView->SetHighColor(168, 168, 168); 1043 fOffscreenView->StrokeRect(r); 1044 fOffscreenView->SetHighColor(80, 80, 80); 1045 fOffscreenView->StrokeLine(BPoint(r.left + 2, r.bottom), r.RightBottom()); 1046 fOffscreenView->StrokeLine(r.RightTop()); 1047 1048 r.InsetBySelf(1, 1); 1049 fOffscreenView->SetHighColor(255, 255, 255); 1050 fOffscreenView->StrokeRect(r); 1051 fOffscreenView->SetHighColor(112, 112, 112); 1052 fOffscreenView->StrokeLine(BPoint(r.left + 1, r.bottom), r.RightBottom()); 1053 fOffscreenView->StrokeLine(r.RightTop()); 1054 1055 r.InsetBySelf(1, 1); 1056 fOffscreenView->SetHighColor(168, 168, 168); 1057 fOffscreenView->FillRect(r); 1058 1059 fOffscreenView->SetHighColor(255, 255, 255); 1060 fOffscreenView->FillRect(BRect(r.right - 1, r.bottom - 1, r.right, r.bottom)); 1061 fOffscreenView->SetHighColor(184, 184, 184); 1062 fOffscreenView->StrokeLine(BPoint(r.right - 9, r.bottom), BPoint(r.right - 2, r.bottom)); 1063 fOffscreenView->StrokeLine(BPoint(r.right, r.bottom - 9), BPoint(r.right, r.bottom - 2)); 1064 1065 // Esc key 1066 _DrawBorder(fOffscreenView, BRect(10, 49, 30, 69)); 1067 1068 // Fx keys 1069 _DrawBorder(fOffscreenView, BRect(46, 49, 120, 69)); 1070 1071 _DrawBorder(fOffscreenView, BRect(127, 49, 201, 69)); 1072 1073 _DrawBorder(fOffscreenView, BRect(208, 49, 282, 69)); 1074 1075 // Pause, PrintScreen, ... 1076 _DrawBorder(fOffscreenView, BRect(297, 49, 353, 69)); 1077 1078 // Insert, pg up ... 1079 _DrawBorder(fOffscreenView, BRect(297, 77, 353, 115)); 1080 1081 fOffscreenView->SetHighColor(80, 80, 80); 1082 fOffscreenView->StrokeLine(BPoint(10, 169), BPoint(10, 77)); 1083 fOffscreenView->StrokeLine(BPoint(282, 77)); 1084 fOffscreenView->SetHighColor(255, 255, 255); 1085 fOffscreenView->StrokeLine(BPoint(282, 169)); 1086 fOffscreenView->StrokeLine(BPoint(253, 169)); 1087 fOffscreenView->SetHighColor(80, 80, 80); 1088 fOffscreenView->StrokeLine(BPoint(253, 151)); 1089 fOffscreenView->SetHighColor(255, 255, 255); 1090 fOffscreenView->StrokeLine(BPoint(238, 151)); 1091 fOffscreenView->StrokeLine(BPoint(238, 169)); 1092 fOffscreenView->StrokeLine(BPoint(63, 169)); 1093 fOffscreenView->SetHighColor(80, 80, 80); 1094 fOffscreenView->StrokeLine(BPoint(63, 151)); 1095 fOffscreenView->SetHighColor(255, 255, 255); 1096 fOffscreenView->StrokeLine(BPoint(39, 151)); 1097 fOffscreenView->StrokeLine(BPoint(39, 169)); 1098 fOffscreenView->StrokeLine(BPoint(11, 169)); 1099 1100 // Arrows 1101 fOffscreenView->SetHighColor(80, 80, 80); 1102 fOffscreenView->StrokeLine(BPoint(297, 169), BPoint(297, 149)); 1103 fOffscreenView->StrokeLine(BPoint(315, 149)); 1104 fOffscreenView->StrokeLine(BPoint(315, 131)); 1105 fOffscreenView->StrokeLine(BPoint(335, 131)); 1106 fOffscreenView->StrokeLine(BPoint(336, 149), BPoint(353, 149)); 1107 fOffscreenView->SetHighColor(255, 255, 255); 1108 fOffscreenView->StrokeLine(BPoint(335, 132), BPoint(335, 149)); 1109 fOffscreenView->StrokeLine(BPoint(353, 150), BPoint(353, 169)); 1110 fOffscreenView->StrokeLine(BPoint(298, 169)); 1111 1112 // numkeys 1113 _DrawBorder(fOffscreenView, BRect(368, 77, 442, 169)); 1114 1115 _DrawLocksBackground(); 1116 1117 // the line separator 1118 r = BRect(11, 40, 353, 43); 1119 fOffscreenView->SetHighColor(255, 255, 255); 1120 fOffscreenView->StrokeLine(r.LeftBottom(), r.LeftTop()); 1121 fOffscreenView->StrokeLine(r.RightTop()); 1122 fOffscreenView->SetHighColor(80, 80, 80); 1123 fOffscreenView->StrokeLine(r.RightBottom()); 1124 fOffscreenView->StrokeLine(r.LeftBottom()); 1125 r.OffsetBySelf(2, 4); 1126 r.bottom = r.top + 1; 1127 fOffscreenView->SetHighColor(136, 136, 136); 1128 fOffscreenView->FillRect(r); 1129 fOffscreenView->FillRect(BRect(354, 41, 355, 43)); 1130 1131 // around the textview 1132 fOffscreenView->SetHighColor(0, 0, 0); 1133 r = BRect(11, 13, Bounds().right - 11, 31); 1134 fOffscreenView->StrokeLine(r.LeftBottom(), r.LeftTop()); 1135 fOffscreenView->StrokeLine(r.RightTop()); 1136 fOffscreenView->SetHighColor(80, 80, 80); 1137 fOffscreenView->StrokeLine(r.LeftBottom() + BPoint(1, 0), 1138 r.LeftTop() + BPoint(1, 1)); 1139 fOffscreenView->StrokeLine(r.RightTop() + BPoint(0,1)); 1140 fOffscreenView->SetHighColor(136, 136, 136); 1141 fOffscreenView->StrokeLine(r.LeftBottom() + BPoint(2, -1), 1142 r.LeftTop() + BPoint(2, 2)); 1143 fOffscreenView->StrokeLine(r.RightTop()+BPoint(0, 2)); 1144 fOffscreenView->StrokeLine(r.LeftBottom()+BPoint(1, 0), 1145 r.LeftBottom() + BPoint(1, 0)); 1146 fOffscreenView->SetHighColor(255, 255, 255); 1147 fOffscreenView->StrokeLine(r.RightTop() + BPoint(0, 1), r.RightBottom()); 1148 fOffscreenView->StrokeLine(r.LeftBottom() + BPoint(2, 0)); 1149 1150 _DrawKeysBackground(); 1151 1152 } 1153 1154 1155 void 1156 MapView::Draw(BRect rect) 1157 { 1158 // draw the background 1159 if (!fBitmap->Lock()) 1160 return; 1161 1162 if (fOffscreenView->Bounds().Intersects(rect)) { 1163 BRegion region(rect); 1164 ConstrainClippingRegion(®ion); 1165 DrawBitmapAsync(fBitmap, B_ORIGIN); 1166 ConstrainClippingRegion(NULL); 1167 } 1168 1169 fBitmap->Unlock(); 1170 1171 // draw symbols and lights 1172 for (uint32 i = 1; i <= 128; i++) 1173 if (fKeysToDraw[i] && rect.Intersects(fKeysRect[i])) 1174 _DrawKey(i); 1175 1176 if (rect.Intersects(BRect(368, 49, 442, 69))) 1177 _DrawLocksLights(); 1178 } 1179 1180 1181 void 1182 MapView::_DrawLocksBackground() 1183 { 1184 _DrawBorder(fOffscreenView, BRect(368, 49, 442, 69)); 1185 1186 escapement_delta delta; 1187 delta.nonspace = 0.0; 1188 BFont font(be_plain_font); 1189 font.SetSize(8.0); 1190 font.SetFlags(B_DISABLE_ANTIALIASING); 1191 font.SetSpacing(B_CHAR_SPACING); 1192 fOffscreenView->SetFont(&font); 1193 BRect lightRect = BRect(372, 53, 386, 56); 1194 1195 fOffscreenView->SetHighColor(80, 80, 80); 1196 fOffscreenView->StrokeLine(lightRect.LeftBottom(), lightRect.RightBottom()); 1197 fOffscreenView->StrokeLine(lightRect.RightTop()); 1198 fOffscreenView->SetHighColor(255, 255, 255); 1199 fOffscreenView->StrokeLine(BPoint(lightRect.right - 1, lightRect.top), 1200 lightRect.LeftTop()); 1201 fOffscreenView->StrokeLine(BPoint(lightRect.left, lightRect.bottom - 1)); 1202 fOffscreenView->SetHighColor(0, 55, 0); 1203 fOffscreenView->FillRect(lightRect.InsetByCopy(1, 1)); 1204 fOffscreenView->SetHighColor(64, 64, 64); 1205 fOffscreenView->DrawString("num", BPoint(lightRect.left - 2, 65), &delta); 1206 1207 lightRect.OffsetBy(26, 0); 1208 fOffscreenView->SetHighColor(80, 80, 80); 1209 fOffscreenView->StrokeLine(lightRect.LeftBottom(), lightRect.RightBottom()); 1210 fOffscreenView->StrokeLine(lightRect.RightTop()); 1211 fOffscreenView->SetHighColor(255, 255, 255); 1212 fOffscreenView->StrokeLine(BPoint(lightRect.right - 1, lightRect.top), 1213 lightRect.LeftTop()); 1214 fOffscreenView->StrokeLine(BPoint(lightRect.left, lightRect.bottom - 1)); 1215 fOffscreenView->SetHighColor(0, 55, 0); 1216 fOffscreenView->FillRect(lightRect.InsetByCopy(1, 1)); 1217 fOffscreenView->SetHighColor(64, 64, 64); 1218 fOffscreenView->DrawString("caps", BPoint(lightRect.left - 2, 65), &delta); 1219 1220 lightRect.OffsetBy(26, 0); 1221 fOffscreenView->SetHighColor(80, 80, 80); 1222 fOffscreenView->StrokeLine(lightRect.LeftBottom(), lightRect.RightBottom()); 1223 fOffscreenView->StrokeLine(lightRect.RightTop()); 1224 fOffscreenView->SetHighColor(255, 255, 255); 1225 fOffscreenView->StrokeLine(BPoint(lightRect.right - 1, lightRect.top), 1226 lightRect.LeftTop()); 1227 fOffscreenView->StrokeLine(BPoint(lightRect.left, lightRect.bottom - 1)); 1228 fOffscreenView->SetHighColor(0, 55, 0); 1229 fOffscreenView->FillRect(lightRect.InsetByCopy(1, 1)); 1230 fOffscreenView->SetHighColor(64, 64, 64); 1231 fOffscreenView->DrawString("scroll", BPoint(lightRect.left - 4, 65), &delta); 1232 } 1233 1234 1235 void MapView::_DrawLocksLights() 1236 { 1237 BRect lightRect = BRect(372, 53, 386, 56); 1238 lightRect.InsetBy(1, 1); 1239 1240 SetHighColor(0, 55, 0); 1241 if (fOldKeyInfo.modifiers & B_NUM_LOCK) 1242 SetHighColor(0, 178, 0); 1243 FillRect(lightRect); 1244 1245 lightRect.OffsetBy(26, 0); 1246 SetHighColor(0, 55, 0); 1247 if (fOldKeyInfo.modifiers & B_CAPS_LOCK) 1248 SetHighColor(0, 178, 0); 1249 FillRect(lightRect); 1250 1251 lightRect.OffsetBy(26, 0); 1252 SetHighColor(0, 55, 0); 1253 if (fOldKeyInfo.modifiers & B_SCROLL_LOCK) 1254 SetHighColor(0, 178, 0); 1255 FillRect(lightRect); 1256 } 1257 1258 1259 void 1260 MapView::_InvalidateKeys() 1261 { 1262 Invalidate(); 1263 } 1264 1265 1266 void 1267 MapView::_InvalidateKey(uint32 keyCode) 1268 { 1269 Invalidate(fKeysRect[keyCode]); 1270 1271 } 1272 1273 1274 void 1275 MapView::_DrawKeysBackground() 1276 { 1277 for (uint32 keyCode = 1; keyCode <= 128; keyCode++){ 1278 1279 BRect r = fKeysRect[keyCode]; 1280 if (!r.IsValid()) 1281 return; 1282 fOffscreenView->SetHighColor(0, 0, 0); 1283 fOffscreenView->StrokeRect(r); 1284 1285 bool vertical = fKeysVertical[keyCode]; 1286 int32 deadKey = fCurrentMap->IsDeadKey(keyCode, fOldKeyInfo.modifiers); 1287 bool secondDeadKey = fCurrentMap->IsDeadSecondKey(keyCode, 1288 fOldKeyInfo.modifiers, fActiveDeadKey); 1289 1290 r.InsetBySelf(1, 1); 1291 if (!secondDeadKey && deadKey == 0) { 1292 fOffscreenView->SetHighColor(64, 64, 64); 1293 fOffscreenView->StrokeRect(r); 1294 1295 fOffscreenView->BeginLineArray(14); 1296 rgb_color color1 = {200, 200, 200}; 1297 fOffscreenView->AddLine(BPoint(r.left, r.bottom - 1), r.LeftTop(), 1298 color1); 1299 fOffscreenView->AddLine(r.LeftTop(), BPoint(r.left+3, r.top), 1300 color1); 1301 rgb_color color2 = {184, 184, 184}; 1302 fOffscreenView->AddLine(BPoint(r.left + 3, r.top), 1303 BPoint(r.left + 6, r.top), color2); 1304 rgb_color color3 = {168, 168, 168}; 1305 fOffscreenView->AddLine(BPoint(r.left + 6, r.top), 1306 BPoint(r.left + 9, r.top), color3); 1307 rgb_color color4 = {152, 152, 152}; 1308 fOffscreenView->AddLine(BPoint(r.left + 9, r.top), 1309 BPoint(r.right - 1, r.top), color4); 1310 1311 r.InsetBySelf(1,1); 1312 fOffscreenView->SetHighColor(255, 255, 255); 1313 fOffscreenView->StrokeRect(r); 1314 1315 rgb_color color6 = {96, 96, 96}; 1316 fOffscreenView->AddLine(r.LeftBottom(), r.RightBottom(), color6); 1317 rgb_color color5 = {160, 160, 160}; 1318 fOffscreenView->AddLine(r.LeftBottom(), r.LeftBottom(), color5); 1319 rgb_color color7 = {64, 64, 64}; 1320 fOffscreenView->AddLine(r.RightBottom(), 1321 BPoint(r.right, r.bottom - 1), color7); 1322 fOffscreenView->AddLine(BPoint(r.right, r.bottom - 1), 1323 BPoint(r.right, r.top - 1), color6); 1324 fOffscreenView->AddLine(BPoint(r.right, r.top - 1), r.RightTop(), 1325 color5); 1326 rgb_color color8 = {255, 255, 255}; 1327 fOffscreenView->AddLine(BPoint(r.left + 1, r.bottom - 1), 1328 BPoint(r.left + 2, r.bottom - 1), color8); 1329 fOffscreenView->AddLine(BPoint(r.left + 2, r.bottom - 1), 1330 BPoint(r.right - 1, r.bottom - 1), color1); 1331 fOffscreenView->AddLine(BPoint(r.right - 1, r.bottom - 1), 1332 BPoint(r.right - 1, r.bottom - 2), color5); 1333 fOffscreenView->AddLine(BPoint(r.right - 1, r.bottom - 2), 1334 BPoint(r.right - 1, r.top + 1), color1); 1335 fOffscreenView->EndLineArray(); 1336 } 1337 1338 r.InsetBySelf(1, 1); 1339 r.bottom -= 1; 1340 BRect fillRect = r; 1341 1342 if (!vertical) { 1343 int32 w1 = 4; 1344 int32 w2 = 3; 1345 if (fKeysRect[keyCode].Width() > 20) { 1346 w1 = 6; 1347 w2 = 6; 1348 } 1349 1350 fillRect.right = fillRect.left + w1; 1351 fOffscreenView->SetHighColor(152, 152, 152); 1352 fOffscreenView->FillRect(fillRect); 1353 fillRect.left += w1; 1354 fillRect.right = fillRect.left + w2; 1355 fOffscreenView->SetHighColor(168, 168, 168); 1356 fOffscreenView->FillRect(fillRect); 1357 fillRect.left += w2; 1358 fillRect.right = r.right - 1; 1359 fOffscreenView->SetHighColor(184, 184, 184); 1360 fOffscreenView->FillRect(fillRect); 1361 } else { 1362 fOffscreenView->SetHighColor(200, 200, 200); 1363 fillRect.right -= 1; 1364 fillRect.bottom = fillRect.top + 2; 1365 fOffscreenView->FillRect(fillRect); 1366 fOffscreenView->SetHighColor(184, 184, 184); 1367 fillRect.OffsetBySelf(0, 3); 1368 fOffscreenView->FillRect(fillRect); 1369 fOffscreenView->SetHighColor(168, 168, 168); 1370 fillRect.OffsetBySelf(0, 3); 1371 fOffscreenView->FillRect(fillRect); 1372 fOffscreenView->SetHighColor(152, 152, 152); 1373 fillRect.OffsetBySelf(0, 3); 1374 fOffscreenView->FillRect(fillRect); 1375 } 1376 } 1377 1378 } 1379 1380 1381 void 1382 MapView::_DrawKey(uint32 keyCode) 1383 { 1384 BRect r = fKeysRect[keyCode]; 1385 if (!r.IsValid()) 1386 return; 1387 1388 bool pressed = (fOldKeyInfo.key_states[keyCode >> 3] & (1 << (7 - keyCode % 8))) || (keyCode == fCurrentMouseKey); 1389 int32 deadKey = fCurrentMap->IsDeadKey(keyCode, fOldKeyInfo.modifiers); 1390 bool secondDeadKey = fCurrentMap->IsDeadSecondKey(keyCode, fOldKeyInfo.modifiers, fActiveDeadKey); 1391 1392 if (!pressed) { 1393 r.InsetBySelf(1, 1); 1394 if (secondDeadKey) { 1395 SetHighColor(255, 0, 0); 1396 StrokeRect(r); 1397 r.InsetBySelf(1, 1); 1398 StrokeRect(r); 1399 } else if (deadKey > 0) { 1400 SetHighColor(255, 255, 0); 1401 StrokeRect(r); 1402 r.InsetBySelf(1, 1); 1403 StrokeRect(r); 1404 } 1405 } else { 1406 r.InsetBySelf(1, 1); 1407 1408 if (secondDeadKey) { 1409 SetHighColor(255, 0, 0); 1410 StrokeRect(r); 1411 r.InsetBySelf(1, 1); 1412 StrokeRect(r); 1413 } else if (deadKey > 0) { 1414 SetHighColor(255, 255, 0); 1415 StrokeRect(r); 1416 r.InsetBySelf(1, 1); 1417 StrokeRect(r); 1418 } else { 1419 SetHighColor(48, 48, 48); 1420 StrokeRect(r); 1421 1422 BeginLineArray(2); 1423 rgb_color color1 = {136, 136, 136}; 1424 AddLine(BPoint(r.left + 1, r.bottom), r.RightBottom(), color1); 1425 AddLine(r.RightBottom(), BPoint(r.right, r.top + 1), color1); 1426 EndLineArray(); 1427 1428 r.InsetBySelf(1, 1); 1429 SetHighColor(72, 72, 72); 1430 StrokeRect(r); 1431 1432 BeginLineArray(4); 1433 rgb_color color2 = {48, 48, 48}; 1434 AddLine(r.LeftTop(), r.LeftTop(), color2); 1435 rgb_color color3 = {152, 152, 152}; 1436 AddLine(BPoint(r.left + 1, r.bottom), r.RightBottom(), color3); 1437 AddLine(r.RightBottom(), r.RightTop(), color3); 1438 rgb_color color4 = {160, 160, 160}; 1439 AddLine(r.RightTop(), r.RightTop(), color4); 1440 EndLineArray(); 1441 } 1442 1443 r.InsetBySelf(1, 1); 1444 SetHighColor(112, 112, 112); 1445 FillRect(r); 1446 SetHighColor(136, 136, 136); 1447 StrokeLine(r.LeftTop(), r.LeftTop()); 1448 } 1449 1450 char *str = NULL; 1451 int32 numBytes; 1452 1453 fCurrentMap->GetChars(keyCode, fOldKeyInfo.modifiers, fActiveDeadKey, &str, &numBytes); 1454 if (str) { 1455 bool hasGlyphs; 1456 if (deadKey > 0) { 1457 delete[] str; 1458 switch (deadKey) { 1459 case 1: str = strdup("'"); break; 1460 case 2: str = strdup("`"); break; 1461 case 3: str = strdup("^"); break; 1462 case 4: str = strdup("\""); break; 1463 case 5: str = strdup("~"); break; 1464 } 1465 } 1466 fCurrentFont.GetHasGlyphs(str, 1, &hasGlyphs); 1467 1468 if (hasGlyphs) { 1469 SetFont(&fCurrentFont); 1470 SetHighColor(0, 0, 0); 1471 SetLowColor(160, 160, 160); 1472 BPoint point = fKeysRect[keyCode].LeftBottom(); 1473 point.x += 5; 1474 point.y -= 5; 1475 if (pressed) { 1476 point.y += 1; 1477 SetLowColor(112, 112, 112); 1478 } 1479 DrawString(str, point); 1480 } 1481 delete[] str; 1482 } 1483 } 1484 1485 1486 void 1487 MapView::_DrawBorder(BView *view, const BRect& rect) 1488 { 1489 rgb_color gray = {80, 80, 80}; 1490 rgb_color white = {255, 255, 255}; 1491 1492 view->BeginLineArray(4); 1493 view->AddLine(rect.LeftTop(), rect.LeftBottom(), gray); 1494 view->AddLine(rect.LeftTop(), rect.RightTop(), gray); 1495 view->AddLine(BPoint(rect.left + 1, rect.bottom), rect.RightBottom(), white); 1496 view->AddLine(rect.RightBottom(), BPoint(rect.right, rect.top + 1), white); 1497 view->EndLineArray(); 1498 } 1499 1500 1501 void 1502 MapView::MessageReceived(BMessage *msg) 1503 { 1504 switch (msg->what) { 1505 case kMsgMenuEditUndo: 1506 fTextView->Undo(be_clipboard); 1507 break; 1508 case kMsgMenuEditCut: 1509 fTextView->Cut(be_clipboard); 1510 break; 1511 case kMsgMenuEditCopy: 1512 fTextView->Copy(be_clipboard); 1513 break; 1514 case kMsgMenuEditPaste: 1515 fTextView->Paste(be_clipboard); 1516 break; 1517 case kMsgMenuEditClear: 1518 fTextView->Clear(); 1519 break; 1520 case kMsgMenuEditSelectAll: 1521 fTextView->SelectAll(); 1522 break; 1523 case B_KEY_DOWN: 1524 case B_KEY_UP: 1525 case B_UNMAPPED_KEY_DOWN: 1526 case B_UNMAPPED_KEY_UP: 1527 case B_MODIFIERS_CHANGED: { 1528 key_info info; 1529 const uint8 *states; 1530 ssize_t size; 1531 1532 if ((msg->FindData("states", B_UINT8_TYPE, reinterpret_cast<const void **>(&states), &size) != B_OK) 1533 || (msg->FindInt32("modifiers", reinterpret_cast<int32 *>(&info.modifiers)) != B_OK)) 1534 break; 1535 1536 if (fOldKeyInfo.modifiers != info.modifiers) { 1537 fOldKeyInfo.modifiers = info.modifiers; 1538 for (int8 i = 0; i < 16; i++) 1539 fOldKeyInfo.key_states[i] = states[i]; 1540 _InvalidateKeys(); 1541 _DrawLocksLights(); 1542 } else { 1543 1544 int32 keyCode = -1; 1545 for (int8 i = 0; i < 16; i++) 1546 if (fOldKeyInfo.key_states[i] != states[i]) { 1547 uint8 stbits = fOldKeyInfo.key_states[i] ^ states[i]; 1548 fOldKeyInfo.key_states[i] = states[i]; 1549 for (int8 j = 7; stbits; j--, stbits >>= 1) 1550 if (stbits & 1) { 1551 keyCode = i * 8 + j; 1552 _InvalidateKey(keyCode); 1553 } 1554 } 1555 1556 if (keyCode < 0) 1557 for (int8 i = 0; i < 16; i++) { 1558 uint8 stbits = states[i]; 1559 for (int8 j = 7; stbits; j--, stbits >>= 1) 1560 if (stbits & 1) { 1561 keyCode = i * 8 + j; 1562 if (!fCurrentMap->IsModifierKey(keyCode)) { 1563 i = 16; 1564 break; 1565 } 1566 } 1567 } 1568 1569 if (Window()->IsActive() 1570 && msg->what == B_KEY_DOWN) { 1571 char *str = NULL; 1572 int32 numBytes; 1573 if (fActiveDeadKey) { 1574 fCurrentMap->GetChars(keyCode, fOldKeyInfo.modifiers, fActiveDeadKey, &str, &numBytes); 1575 if (numBytes > 0) { 1576 fTextView->FakeKeyDown(str, numBytes); 1577 } 1578 fActiveDeadKey = 0; 1579 _InvalidateKeys(); 1580 } else { 1581 fCurrentMap->GetChars(keyCode, fOldKeyInfo.modifiers, fActiveDeadKey, &str, &numBytes); 1582 fActiveDeadKey = fCurrentMap->IsDeadKey(keyCode, fOldKeyInfo.modifiers); 1583 if (fActiveDeadKey) 1584 _InvalidateKeys(); 1585 else if (numBytes > 0) { 1586 fTextView->FakeKeyDown(str, numBytes); 1587 } 1588 } 1589 delete[] str; 1590 } 1591 } 1592 break; 1593 } 1594 default: 1595 BControl::MessageReceived(msg); 1596 } 1597 } 1598 1599 1600 void 1601 MapView::KeyDown(const char* bytes, int32 numBytes) 1602 { 1603 MessageReceived(Window()->CurrentMessage()); 1604 } 1605 1606 1607 void 1608 MapView::KeyUp(const char* bytes, int32 numBytes) 1609 { 1610 MessageReceived(Window()->CurrentMessage()); 1611 } 1612 1613 1614 void 1615 MapView::MouseDown(BPoint point) 1616 { 1617 uint32 buttons; 1618 GetMouse(&point, &buttons); 1619 if (buttons & B_PRIMARY_MOUSE_BUTTON) { 1620 fCurrentMouseKey = 0; 1621 for (int32 i = 0; i < 128; i++) { 1622 if (fKeysRect[i].IsValid() && fKeysRect[i].Contains(point)) { 1623 fCurrentMouseKey = i; 1624 _DrawKey(fCurrentMouseKey); 1625 char *str = NULL; 1626 int32 numBytes; 1627 fCurrentMap->GetChars(fCurrentMouseKey, fOldKeyInfo.modifiers, fActiveDeadKey, &str, &numBytes); 1628 if (numBytes > 0) 1629 fTextView->FakeKeyDown(str, numBytes); 1630 1631 delete[] str; 1632 SetTracking(true); 1633 SetMouseEventMask(B_POINTER_EVENTS, 1634 B_LOCK_WINDOW_FOCUS | B_NO_POINTER_HISTORY); 1635 break; 1636 } 1637 } 1638 } 1639 } 1640 1641 1642 void 1643 MapView::MouseUp(BPoint point) 1644 { 1645 if (IsTracking()) 1646 SetTracking(false); 1647 uint32 value = fCurrentMouseKey; 1648 fCurrentMouseKey = 0; 1649 _InvalidateKey(value); 1650 } 1651 1652 1653 void 1654 MapView::MouseMoved(BPoint point, uint32 transit, const BMessage *msg) 1655 { 1656 if (IsTracking()) { 1657 uint32 value = fCurrentMouseKey; 1658 for (int32 i = 0; i < 128; i++) { 1659 if (fKeysRect[i].Contains(point) && !fKeysRect[value].Contains(point)) { 1660 fCurrentMouseKey = i; 1661 _InvalidateKey(value); 1662 _InvalidateKey(fCurrentMouseKey); 1663 char *str = NULL; 1664 int32 numBytes; 1665 fCurrentMap->GetChars(fCurrentMouseKey, fOldKeyInfo.modifiers, fActiveDeadKey, &str, &numBytes); 1666 if (numBytes > 0) { 1667 fTextView->FakeKeyDown(str, numBytes); 1668 delete[] str; 1669 } 1670 break; 1671 } 1672 } 1673 } 1674 BControl::MouseMoved(point, transit, msg); 1675 } 1676 1677 1678 void 1679 MapView::SetFontFamily(const font_family family) 1680 { 1681 fCurrentFont.SetFamilyAndStyle(family, NULL); 1682 fTextView->SetFontAndColor(&fCurrentFont); 1683 } 1684