1 /* 2 * Copyright 2001-2015, Haiku, Inc. 3 * Copyright 2003-2004 Kian Duffy, myob@users.sourceforge.net 4 * Parts Copyright 1998-1999 Kazuho Okui and Takashi Murai. 5 * All rights reserved. Distributed under the terms of the MIT license. 6 */ 7 8 9 #include "AppearPrefView.h" 10 11 #include <stdio.h> 12 #include <stdlib.h> 13 14 #include <Button.h> 15 #include <Catalog.h> 16 #include <CharacterSet.h> 17 #include <CharacterSetRoster.h> 18 #include <CheckBox.h> 19 #include <ColorControl.h> 20 #include <LayoutBuilder.h> 21 #include <Locale.h> 22 #include <Menu.h> 23 #include <MenuField.h> 24 #include <MenuItem.h> 25 #include <PopUpMenu.h> 26 #include <TextControl.h> 27 #include <View.h> 28 29 #include "Colors.h" 30 #include "Globals.h" 31 #include "PrefHandler.h" 32 #include "TermConst.h" 33 #include "TermWindow.h" 34 35 36 #undef B_TRANSLATION_CONTEXT 37 #define B_TRANSLATION_CONTEXT "Terminal AppearancePrefView" 38 39 40 41 // #pragma mark - 42 43 44 AppearancePrefView::AppearancePrefView(const char* name, 45 const BMessenger& messenger) 46 : 47 BGroupView(name, B_VERTICAL, 5), 48 fTerminalMessenger(messenger) 49 { 50 const char* kColorTable[] = { 51 B_TRANSLATE_MARK("Text"), 52 B_TRANSLATE_MARK("Background"), 53 B_TRANSLATE_MARK("Cursor"), 54 B_TRANSLATE_MARK("Text under cursor"), 55 B_TRANSLATE_MARK("Selected text"), 56 B_TRANSLATE_MARK("Selected background"), 57 NULL 58 }; 59 60 fBlinkCursor = new BCheckBox( 61 B_TRANSLATE("Blinking cursor"), 62 new BMessage(MSG_BLINK_CURSOR_CHANGED)); 63 64 fAllowBold = new BCheckBox( 65 B_TRANSLATE("Allow bold text"), 66 new BMessage(MSG_ALLOW_BOLD_CHANGED)); 67 68 fUseOptionAsMetaKey = new BCheckBox( 69 B_TRANSLATE("Use left Option as Meta key"), 70 new BMessage(MSG_USE_OPTION_AS_META_CHANGED)); 71 72 fWarnOnExit = new BCheckBox( 73 B_TRANSLATE("Confirm exit if active programs exist"), 74 new BMessage(MSG_WARN_ON_EXIT_CHANGED)); 75 76 BMenu* fontMenu = _MakeFontMenu(MSG_HALF_FONT_CHANGED, 77 PrefHandler::Default()->getString(PREF_HALF_FONT_FAMILY), 78 PrefHandler::Default()->getString(PREF_HALF_FONT_STYLE)); 79 fFontField = new BMenuField(B_TRANSLATE("Font:"), fontMenu); 80 81 BMenu* sizeMenu = new (std::nothrow) BPopUpMenu( 82 B_TRANSLATE_COMMENT("Custom", "Window size")); 83 if (sizeMenu != NULL) { 84 TermWindow::MakeWindowSizeMenu(sizeMenu); 85 sizeMenu->SetLabelFromMarked(true); 86 } 87 fWindowSizeField = new BMenuField(B_TRANSLATE("Window size:"), sizeMenu); 88 89 BMenu* encodingMenu = new (std::nothrow) BPopUpMenu("Text encoding"); 90 if (encodingMenu != NULL) { 91 TermWindow::MakeEncodingMenu(encodingMenu); 92 encodingMenu->SetLabelFromMarked(true); 93 } 94 fEncodingField = new BMenuField(B_TRANSLATE("Encoding:"), encodingMenu); 95 96 BPopUpMenu* schemesPopUp = _MakeColorSchemeMenu(MSG_COLOR_SCHEME_CHANGED, 97 gPredefinedColorSchemes, gPredefinedColorSchemes[0]); 98 fColorSchemeField = new BMenuField(B_TRANSLATE("Color scheme:"), 99 schemesPopUp); 100 101 BPopUpMenu* colorsPopUp = _MakeMenu(MSG_COLOR_FIELD_CHANGED, kColorTable, 102 kColorTable[0]); 103 104 fColorField = new BMenuField(B_TRANSLATE("Color:"), colorsPopUp); 105 106 fTabTitle = new BTextControl("tabTitle", B_TRANSLATE("Tab title:"), "", 107 NULL); 108 fTabTitle->SetModificationMessage( 109 new BMessage(MSG_TAB_TITLE_SETTING_CHANGED)); 110 fTabTitle->SetToolTip(BString(B_TRANSLATE( 111 "The pattern specifying the tab titles. The following placeholders\n" 112 "can be used:")) << "\n" << kTooTipSetTabTitlePlaceholders 113 << "\n" << kToolTipCommonTitlePlaceholders); 114 115 fWindowTitle = new BTextControl("windowTitle", B_TRANSLATE("Window title:"), 116 "", NULL); 117 fWindowTitle->SetModificationMessage( 118 new BMessage(MSG_WINDOW_TITLE_SETTING_CHANGED)); 119 fWindowTitle->SetToolTip(BString(B_TRANSLATE( 120 "The pattern specifying the window titles. The following placeholders\n" 121 "can be used:")) << "\n" << kTooTipSetWindowTitlePlaceholders 122 << "\n" << kToolTipCommonTitlePlaceholders); 123 124 BLayoutBuilder::Group<>(this) 125 .SetInsets(5, 5, 5, 5) 126 .AddGrid(5, 5) 127 .Add(fTabTitle->CreateLabelLayoutItem(), 0, 0) 128 .Add(fTabTitle->CreateTextViewLayoutItem(), 1, 0) 129 .Add(fWindowTitle->CreateLabelLayoutItem(), 0, 1) 130 .Add(fWindowTitle->CreateTextViewLayoutItem(), 1, 1) 131 .Add(fWindowSizeField->CreateLabelLayoutItem(), 0, 2) 132 .Add(fWindowSizeField->CreateMenuBarLayoutItem(), 1, 2) 133 .Add(fFontField->CreateLabelLayoutItem(), 0, 3) 134 .Add(fFontField->CreateMenuBarLayoutItem(), 1, 3) 135 .Add(fEncodingField->CreateLabelLayoutItem(), 0, 4) 136 .Add(fEncodingField->CreateMenuBarLayoutItem(), 1, 4) 137 .Add(fColorSchemeField->CreateLabelLayoutItem(), 0, 5) 138 .Add(fColorSchemeField->CreateMenuBarLayoutItem(), 1, 5) 139 .Add(fColorField->CreateLabelLayoutItem(), 0, 6) 140 .Add(fColorField->CreateMenuBarLayoutItem(), 1, 6) 141 .End() 142 .AddGlue() 143 .Add(fColorControl = new BColorControl(BPoint(10, 10), 144 B_CELLS_32x8, 8.0, "", new BMessage(MSG_COLOR_CHANGED))) 145 .Add(fBlinkCursor) 146 .Add(fAllowBold) 147 .Add(fUseOptionAsMetaKey) 148 .Add(fWarnOnExit); 149 150 fTabTitle->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); 151 fWindowTitle->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); 152 fFontField->SetAlignment(B_ALIGN_RIGHT); 153 fWindowSizeField->SetAlignment(B_ALIGN_RIGHT); 154 fEncodingField->SetAlignment(B_ALIGN_RIGHT); 155 fColorField->SetAlignment(B_ALIGN_RIGHT); 156 fColorSchemeField->SetAlignment(B_ALIGN_RIGHT); 157 158 Revert(); 159 160 BTextControl* redInput = (BTextControl*)fColorControl->ChildAt(0); 161 BTextControl* greenInput = (BTextControl*)fColorControl->ChildAt(1); 162 BTextControl* blueInput = (BTextControl*)fColorControl->ChildAt(2); 163 164 redInput->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); 165 greenInput->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); 166 blueInput->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); 167 } 168 169 170 void 171 AppearancePrefView::Revert() 172 { 173 PrefHandler* pref = PrefHandler::Default(); 174 175 fTabTitle->SetText(pref->getString(PREF_TAB_TITLE)); 176 fWindowTitle->SetText(pref->getString(PREF_WINDOW_TITLE)); 177 178 fBlinkCursor->SetValue(pref->getBool(PREF_BLINK_CURSOR)); 179 fAllowBold->SetValue(pref->getBool(PREF_ALLOW_BOLD)); 180 fUseOptionAsMetaKey->SetValue(pref->getBool(PREF_USE_OPTION_AS_META)); 181 fWarnOnExit->SetValue(pref->getBool(PREF_WARN_ON_EXIT)); 182 183 _SetCurrentColorScheme(); 184 _SetEncoding(pref->getString(PREF_TEXT_ENCODING)); 185 _SetWindowSize(pref->getInt32(PREF_ROWS), pref->getInt32(PREF_COLS)); 186 fColorControl->SetValue(pref->getRGB(PREF_TEXT_FORE_COLOR)); 187 188 const char* family = pref->getString(PREF_HALF_FONT_FAMILY); 189 const char* style = pref->getString(PREF_HALF_FONT_STYLE); 190 const char* size = pref->getString(PREF_HALF_FONT_SIZE); 191 192 _MarkSelectedFont(family, style, size); 193 } 194 195 196 void 197 AppearancePrefView::AttachedToWindow() 198 { 199 fTabTitle->SetTarget(this); 200 fWindowTitle->SetTarget(this); 201 fBlinkCursor->SetTarget(this); 202 fAllowBold->SetTarget(this); 203 fUseOptionAsMetaKey->SetTarget(this); 204 fWarnOnExit->SetTarget(this); 205 206 fFontField->Menu()->SetTargetForItems(this); 207 for (int32 i = 0; i < fFontField->Menu()->CountItems(); i++) { 208 BMenu* fontSizeMenu = fFontField->Menu()->SubmenuAt(i); 209 if (fontSizeMenu == NULL) 210 continue; 211 212 fontSizeMenu->SetTargetForItems(this); 213 } 214 215 fColorControl->SetTarget(this); 216 fColorField->Menu()->SetTargetForItems(this); 217 fColorSchemeField->Menu()->SetTargetForItems(this); 218 fWindowSizeField->Menu()->SetTargetForItems(this); 219 fEncodingField->Menu()->SetTargetForItems(this); 220 221 _SetCurrentColorScheme(); 222 } 223 224 225 void 226 227 AppearancePrefView::MessageReceived(BMessage* msg) 228 { 229 bool modified = false; 230 231 switch (msg->what) { 232 case MSG_HALF_FONT_CHANGED: 233 { 234 const char* family = NULL; 235 const char* style = NULL; 236 const char* size = NULL; 237 if (msg->FindString("font_family", &family) != B_OK 238 || msg->FindString("font_style", &style) != B_OK 239 || msg->FindString("font_size", &size) != B_OK) { 240 break; 241 } 242 243 PrefHandler* pref = PrefHandler::Default(); 244 const char* currentFamily 245 = pref->getString(PREF_HALF_FONT_FAMILY); 246 const char* currentStyle 247 = pref->getString(PREF_HALF_FONT_STYLE); 248 const char* currentSize 249 = pref->getString(PREF_HALF_FONT_SIZE); 250 251 if (currentFamily == NULL || strcmp(currentFamily, family) != 0 252 || currentStyle == NULL || strcmp(currentStyle, style) != 0 253 || currentSize == NULL || strcmp(currentSize, size) != 0) { 254 pref->setString(PREF_HALF_FONT_FAMILY, family); 255 pref->setString(PREF_HALF_FONT_STYLE, style); 256 pref->setString(PREF_HALF_FONT_SIZE, size); 257 _MarkSelectedFont(family, style, size); 258 modified = true; 259 } 260 break; 261 } 262 263 case MSG_COLOR_CHANGED: 264 { 265 const BMessage* itemMessage 266 = fColorField->Menu()->FindMarked()->Message(); 267 const char* label = NULL; 268 if (itemMessage->FindString("label", &label) != B_OK) 269 break; 270 rgb_color oldColor = PrefHandler::Default()->getRGB(label); 271 if (oldColor != fColorControl->ValueAsColor()) { 272 BMenuItem* item = fColorSchemeField->Menu()->FindMarked(); 273 if (strcmp(item->Label(), gCustomColorScheme.name) != 0) { 274 item->SetMarked(false); 275 item = fColorSchemeField->Menu()->FindItem( 276 gCustomColorScheme.name); 277 if (item) 278 item->SetMarked(true); 279 } 280 281 PrefHandler::Default()->setRGB(label, 282 fColorControl->ValueAsColor()); 283 modified = true; 284 } 285 break; 286 } 287 288 case MSG_COLOR_SCHEME_CHANGED: 289 { 290 color_scheme* newScheme = NULL; 291 if (msg->FindPointer("color_scheme", 292 (void**)&newScheme) == B_OK) { 293 _ChangeColorScheme(newScheme); 294 const char* label = NULL; 295 if (fColorField->Menu()->FindMarked()->Message()->FindString( 296 "label", &label) == B_OK) 297 fColorControl->SetValue( 298 PrefHandler::Default()->getRGB(label)); 299 modified = true; 300 } 301 break; 302 } 303 304 case MSG_COLOR_FIELD_CHANGED: 305 { 306 const char* label = NULL; 307 if (msg->FindString("label", &label) == B_OK) 308 fColorControl->SetValue(PrefHandler::Default()->getRGB(label)); 309 break; 310 } 311 312 case MSG_COLS_CHANGED: 313 { 314 int rows = msg->FindInt32("rows"); 315 int columns = msg->FindInt32("columns"); 316 _SetWindowSize(rows, columns); 317 PrefHandler* handler = PrefHandler::Default(); 318 if (handler->getInt32(PREF_ROWS) != rows) { 319 PrefHandler::Default()->setInt32(PREF_ROWS, rows); 320 modified = true; 321 } 322 if (handler->getInt32(PREF_COLS) != columns) { 323 PrefHandler::Default()->setInt32(PREF_COLS, columns); 324 modified = true; 325 } 326 327 break; 328 } 329 330 case MSG_BLINK_CURSOR_CHANGED: 331 if (PrefHandler::Default()->getBool(PREF_BLINK_CURSOR) 332 != fBlinkCursor->Value()) { 333 PrefHandler::Default()->setBool(PREF_BLINK_CURSOR, 334 fBlinkCursor->Value()); 335 modified = true; 336 } 337 break; 338 339 case MSG_ALLOW_BOLD_CHANGED: 340 if (PrefHandler::Default()->getBool(PREF_ALLOW_BOLD) 341 != fAllowBold->Value()) { 342 PrefHandler::Default()->setBool(PREF_ALLOW_BOLD, 343 fAllowBold->Value()); 344 modified = true; 345 } 346 break; 347 348 case MSG_USE_OPTION_AS_META_CHANGED: 349 if (PrefHandler::Default()->getBool(PREF_USE_OPTION_AS_META) 350 != fUseOptionAsMetaKey->Value()) { 351 PrefHandler::Default()->setBool(PREF_USE_OPTION_AS_META, 352 fUseOptionAsMetaKey->Value()); 353 modified = true; 354 } 355 break; 356 357 case MSG_WARN_ON_EXIT_CHANGED: 358 if (PrefHandler::Default()->getBool(PREF_WARN_ON_EXIT) 359 != fWarnOnExit->Value()) { 360 PrefHandler::Default()->setBool(PREF_WARN_ON_EXIT, 361 fWarnOnExit->Value()); 362 modified = true; 363 } 364 break; 365 366 case MSG_TAB_TITLE_SETTING_CHANGED: 367 { 368 BString oldValue(PrefHandler::Default()->getString(PREF_TAB_TITLE)); 369 if (oldValue != fTabTitle->Text()) { 370 PrefHandler::Default()->setString(PREF_TAB_TITLE, 371 fTabTitle->Text()); 372 modified = true; 373 } 374 break; 375 } 376 377 case MSG_WINDOW_TITLE_SETTING_CHANGED: 378 { 379 BString oldValue(PrefHandler::Default()->getString( 380 PREF_WINDOW_TITLE)); 381 if (oldValue != fWindowTitle->Text()) { 382 PrefHandler::Default()->setString(PREF_WINDOW_TITLE, 383 fWindowTitle->Text()); 384 modified = true; 385 } 386 break; 387 } 388 389 default: 390 BView::MessageReceived(msg); 391 return; 392 } 393 394 if (modified) { 395 fTerminalMessenger.SendMessage(msg); 396 397 BMessenger messenger(this); 398 messenger.SendMessage(MSG_PREF_MODIFIED); 399 } 400 } 401 402 403 void 404 AppearancePrefView::_ChangeColorScheme(color_scheme* scheme) 405 { 406 PrefHandler* pref = PrefHandler::Default(); 407 408 pref->setRGB(PREF_TEXT_FORE_COLOR, scheme->text_fore_color); 409 pref->setRGB(PREF_TEXT_BACK_COLOR, scheme->text_back_color); 410 pref->setRGB(PREF_SELECT_FORE_COLOR, scheme->select_fore_color); 411 pref->setRGB(PREF_SELECT_BACK_COLOR, scheme->select_back_color); 412 pref->setRGB(PREF_CURSOR_FORE_COLOR, scheme->cursor_fore_color); 413 pref->setRGB(PREF_CURSOR_BACK_COLOR, scheme->cursor_back_color); 414 } 415 416 417 void 418 AppearancePrefView::_SetCurrentColorScheme() 419 { 420 PrefHandler* pref = PrefHandler::Default(); 421 422 gCustomColorScheme.text_fore_color = pref->getRGB(PREF_TEXT_FORE_COLOR); 423 gCustomColorScheme.text_back_color = pref->getRGB(PREF_TEXT_BACK_COLOR); 424 gCustomColorScheme.select_fore_color = pref->getRGB(PREF_SELECT_FORE_COLOR); 425 gCustomColorScheme.select_back_color = pref->getRGB(PREF_SELECT_BACK_COLOR); 426 gCustomColorScheme.cursor_fore_color = pref->getRGB(PREF_CURSOR_FORE_COLOR); 427 gCustomColorScheme.cursor_back_color = pref->getRGB(PREF_CURSOR_BACK_COLOR); 428 429 const char* currentSchemeName = NULL; 430 431 for (const color_scheme** schemes = gPredefinedColorSchemes; 432 *schemes != NULL; schemes++) { 433 if (gCustomColorScheme == **schemes) { 434 currentSchemeName = (*schemes)->name; 435 break; 436 } 437 } 438 439 // If the scheme is not one of the known ones, assume a custom one. 440 if (currentSchemeName == NULL) 441 currentSchemeName = "Custom"; 442 443 for (int32 i = 0; i < fColorSchemeField->Menu()->CountItems(); i++) { 444 BMenuItem* item = fColorSchemeField->Menu()->ItemAt(i); 445 if (strcmp(item->Label(), currentSchemeName) == 0) { 446 item->SetMarked(true); 447 break; 448 } 449 } 450 } 451 452 453 void 454 AppearancePrefView::_SetEncoding(const char* name) 455 { 456 const BPrivate::BCharacterSet* charset 457 = BPrivate::BCharacterSetRoster::FindCharacterSetByName(name); 458 if (charset == NULL) 459 return; 460 int code = charset->GetConversionID(); 461 for (int32 i = 0; i < fEncodingField->Menu()->CountItems(); i++) { 462 BMenuItem* item = fEncodingField->Menu()->ItemAt(i); 463 BMessage* msg = item->Message(); 464 if (msg->FindInt32("op") == code) { 465 item->SetMarked(true); 466 break; 467 } 468 } 469 } 470 471 472 void 473 AppearancePrefView::_SetWindowSize(int rows, int cols) 474 { 475 for (int32 i = 0; i < fWindowSizeField->Menu()->CountItems(); i++) { 476 BMenuItem* item = fWindowSizeField->Menu()->ItemAt(i); 477 BMessage* msg = item->Message(); 478 if (msg->FindInt32("rows") == rows && msg->FindInt32("columns") == cols) { 479 item->SetMarked(true); 480 break; 481 } 482 } 483 } 484 485 486 /*static*/ BMenu* 487 AppearancePrefView::_MakeFontMenu(uint32 command, 488 const char* defaultFamily, const char* defaultStyle) 489 { 490 BPopUpMenu* menu = new BPopUpMenu(""); 491 int32 numFamilies = count_font_families(); 492 for (int32 i = 0; i < numFamilies; i++) { 493 font_family family; 494 uint32 flags; 495 if (get_font_family(i, &family, &flags) == B_OK) { 496 BFont font; 497 font_style style; 498 int32 numStyles = count_font_styles(family); 499 for (int32 j = 0; j < numStyles; j++) { 500 if (get_font_style(family, j, &style) == B_OK) { 501 font.SetFamilyAndStyle(family, style); 502 if (IsFontUsable(font)) { 503 BMessage* message = new BMessage(command); 504 const char* size 505 = PrefHandler::Default()->getString(PREF_HALF_FONT_SIZE); 506 message->AddString("font_family", family); 507 message->AddString("font_style", style); 508 message->AddString("font_size", size); 509 char fontMenuLabel[134]; 510 snprintf(fontMenuLabel, sizeof(fontMenuLabel), 511 "%s - %s", family, style); 512 BMenu* fontSizeMenu = _MakeFontSizeMenu(fontMenuLabel, 513 MSG_HALF_FONT_CHANGED, family, style, size); 514 BMenuItem* item = new BMenuItem(fontSizeMenu, message); 515 menu->AddItem(item); 516 if (strcmp(defaultFamily, family) == 0 517 && strcmp(defaultStyle, style) == 0) 518 item->SetMarked(true); 519 } 520 } 521 } 522 } 523 } 524 525 if (menu->FindMarked() == NULL) 526 menu->ItemAt(0)->SetMarked(true); 527 528 return menu; 529 } 530 531 532 /*static*/ BMenu* 533 AppearancePrefView::_MakeFontSizeMenu(const char* label, uint32 command, 534 const char* family, const char* style, const char* size) 535 { 536 BMenu* menu = new BMenu(label); 537 menu->SetRadioMode(true); 538 menu->SetLabelFromMarked(false); 539 540 int32 sizes[] = { 541 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 24, 28, 32, 36, 0 542 }; 543 544 bool found = false; 545 546 for (uint32 i = 0; sizes[i]; i++) { 547 BString fontSize; 548 fontSize << sizes[i]; 549 BMessage* message = new BMessage(command); 550 message->AddString("font_family", family); 551 message->AddString("font_style", style); 552 message->AddString("font_size", fontSize.String()); 553 BMenuItem* item = new BMenuItem(fontSize.String(), message); 554 menu->AddItem(item); 555 if (sizes[i] == atoi(size)) { 556 item->SetMarked(true); 557 found = true; 558 } 559 } 560 561 if (!found) { 562 for (uint32 i = 0; sizes[i]; i++) { 563 if (sizes[i] > atoi(size)) { 564 BMessage* message = new BMessage(command); 565 message->AddString("font_family", family); 566 message->AddString("font_style", style); 567 message->AddString("font_size", size); 568 BMenuItem* item = new BMenuItem(size, message); 569 item->SetMarked(true); 570 menu->AddItem(item, i); 571 break; 572 } 573 } 574 } 575 576 return menu; 577 } 578 579 580 /*static*/ BPopUpMenu* 581 AppearancePrefView::_MakeMenu(uint32 msg, const char** items, 582 const char* defaultItemName) 583 { 584 BPopUpMenu* menu = new BPopUpMenu(""); 585 586 while (*items) { 587 if (strcmp((*items), "") == 0) 588 menu->AddSeparatorItem(); 589 else { 590 BMessage* message = new BMessage(msg); 591 message->AddString("label", *items); 592 BMenuItem* item = new BMenuItem(B_TRANSLATE(*items), message); 593 menu->AddItem(item); 594 if (strcmp(*items, defaultItemName) == 0) 595 item->SetMarked(true); 596 } 597 598 items++; 599 } 600 601 return menu; 602 } 603 604 605 /*static*/ BPopUpMenu* 606 AppearancePrefView::_MakeColorSchemeMenu(uint32 msg, const color_scheme** items, 607 const color_scheme* defaultItemName) 608 { 609 BPopUpMenu* menu = new BPopUpMenu(""); 610 611 int32 i = 0; 612 while (*items) { 613 if (strcmp((*items)->name, "") == 0) 614 menu->AddSeparatorItem(); 615 else { 616 BMessage* message = new BMessage(msg); 617 message->AddPointer("color_scheme", (const void*)*items); 618 menu->AddItem(new BMenuItem((*items)->name, message)); 619 } 620 621 items++; 622 i++; 623 } 624 return menu; 625 } 626 627 628 void 629 AppearancePrefView::_MarkSelectedFont(const char* family, const char* style, 630 const char* size) 631 { 632 char fontMenuLabel[134]; 633 snprintf(fontMenuLabel, sizeof(fontMenuLabel), "%s - %s", family, style); 634 635 // mark the selected font 636 BMenuItem* selectedFont = fFontField->Menu()->FindItem(fontMenuLabel); 637 if (selectedFont != NULL) 638 selectedFont->SetMarked(true); 639 640 // mark the selected font size on all font menus 641 for (int32 i = 0; i < fFontField->Menu()->CountItems(); i++) { 642 BMenu* fontSizeMenu = fFontField->Menu()->SubmenuAt(i); 643 if (fontSizeMenu == NULL) 644 continue; 645 646 BMenuItem* item = fontSizeMenu->FindItem(size); 647 if (item != NULL) 648 item->SetMarked(true); 649 } 650 } 651