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