2 * Copyright 2001-2015, Haiku.
3 * Distributed under the terms of the MIT License.
7 * DarkWyrm <bpmagic@columbus.rr.com>
8 * Axel Dörfler, axeld@pinc-software.de
9 * Philippe Saint-Pierre, stpere@gmail.com
10 * Stephan Aßmus <superstippi@gmx.de>
14 #include "FontSelectionView.h"
19 #include <MenuField.h>
21 #include <PopUpMenu.h>
23 #include <StringView.h>
24 #include <LayoutItem.h>
25 #include <GroupLayoutBuilder.h>
30 #undef B_TRANSLATION_CONTEXT
31 #define B_TRANSLATION_CONTEXT "Font Selection view"
34 #define INSTANT_UPDATE
35 // if defined, the system font will be updated immediately, and not
38 static const float kMinSize
= 8.0;
39 static const float kMaxSize
= 24.0;
43 extern void _set_system_font_(const char *which
, font_family family
,
44 font_style style
, float size
);
45 extern status_t
_get_system_default_font_(const char* which
,
46 font_family family
, font_style style
, float* _size
);
49 #ifdef B_BEOS_VERSION_DANO
50 // this call only exists under R5
52 _set_system_font_(const char *which
, font_family family
,
53 font_style style
, float size
)
55 puts("you don't have _set_system_font_()");
59 #if !defined(HAIKU_TARGET_PLATFORM_HAIKU) && !defined(HAIKU_TARGET_PLATFORM_LIBBE_TEST)
60 // this call only exists under Haiku (and the test environment)
62 _get_system_default_font_(const char* which
, font_family family
,
63 font_style style
, float* _size
)
65 puts("you don't have _get_system_default_font_()");
74 FontSelectionView::FontSelectionView(const char* name
,
75 const char* label
, const BFont
* currentFont
)
77 BView(name
, B_WILL_DRAW
),
80 if (currentFont
== NULL
) {
81 if (!strcmp(Name(), "plain"))
82 fCurrentFont
= *be_plain_font
;
83 else if (!strcmp(Name(), "bold"))
84 fCurrentFont
= *be_bold_font
;
85 else if (!strcmp(Name(), "fixed"))
86 fCurrentFont
= *be_fixed_font
;
87 else if (!strcmp(Name(), "menu")) {
91 fCurrentFont
.SetFamilyAndStyle(info
.f_family
, info
.f_style
);
92 fCurrentFont
.SetSize(info
.font_size
);
95 fCurrentFont
= *currentFont
;
97 fSavedFont
= fCurrentFont
;
99 fSizesMenu
= new BPopUpMenu("size menu");
102 fFontsMenu
= new BPopUpMenu("font menu");
105 fFontsMenuField
= new BMenuField("fonts", label
, fFontsMenu
);
106 fFontsMenuField
->SetAlignment(B_ALIGN_RIGHT
);
109 fSizesMenuField
= new BMenuField("size", B_TRANSLATE("Size:"), fSizesMenu
);
110 fSizesMenuField
->SetAlignment(B_ALIGN_RIGHT
);
113 fPreviewText
= new BStringView("preview text",
114 B_TRANSLATE_COMMENT("The quick brown fox jumps over the lazy dog.",
115 "Don't translate this literally ! Use a phrase showing all chars "
118 fPreviewText
->SetFont(&fCurrentFont
);
119 fPreviewText
->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED
, B_SIZE_UNSET
));
121 // box around preview
122 fPreviewBox
= new BBox("preview box", B_WILL_DRAW
| B_FRAME_EVENTS
);
123 fPreviewBox
->AddChild(BGroupLayoutBuilder(B_HORIZONTAL
)
125 .SetInsets(B_USE_SMALL_SPACING
, B_USE_SMALL_SPACING
,
126 B_USE_SMALL_SPACING
, B_USE_SMALL_SPACING
)
132 FontSelectionView::~FontSelectionView()
134 #ifndef INSTANT_UPDATE
141 FontSelectionView::SetTarget(BHandler
* messageTarget
)
143 fMessageTarget
= messageTarget
;
144 fSizesMenu
->SetTargetForItems(fMessageTarget
);
149 FontSelectionView::GetPreviewBox()
156 FontSelectionView::MessageReceived(BMessage
*msg
)
162 if (msg
->FindInt32("size", &size
) != B_OK
163 || size
== fCurrentFont
.Size())
166 fCurrentFont
.SetSize(size
);
167 _UpdateFontPreview();
174 if (msg
->FindString("family", &family
) != B_OK
)
178 fCurrentFont
.GetFamilyAndStyle(NULL
, &style
);
180 BMenuItem
*familyItem
= fFontsMenu
->FindItem(family
);
181 if (familyItem
!= NULL
) {
182 _SelectCurrentFont(false);
184 BMenuItem
*item
= familyItem
->Submenu()->FindItem(style
);
186 item
= familyItem
->Submenu()->ItemAt(0);
189 item
->SetMarked(true);
190 fCurrentFont
.SetFamilyAndStyle(family
, item
->Label());
191 _UpdateFontPreview();
201 if (msg
->FindString("family", &family
) != B_OK
202 || msg
->FindString("style", &style
) != B_OK
)
205 BMenuItem
*familyItem
= fFontsMenu
->FindItem(family
);
209 _SelectCurrentFont(false);
210 familyItem
->SetMarked(true);
212 fCurrentFont
.SetFamilyAndStyle(family
, style
);
213 _UpdateFontPreview();
218 BView::MessageReceived(msg
);
224 FontSelectionView::CreateSizesLabelLayoutItem()
226 return fSizesMenuField
->CreateLabelLayoutItem();
231 FontSelectionView::CreateSizesMenuBarLayoutItem()
233 return fSizesMenuField
->CreateMenuBarLayoutItem();
238 FontSelectionView::CreateFontsLabelLayoutItem()
240 return fFontsMenuField
->CreateLabelLayoutItem();
245 FontSelectionView::CreateFontsMenuBarLayoutItem()
247 return fFontsMenuField
->CreateMenuBarLayoutItem();
252 FontSelectionView::_BuildSizesMenu()
254 const int32 sizes
[] = {7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 19, 20,
258 for (int32 i
= 0; sizes
[i
]; i
++) {
259 int32 size
= sizes
[i
];
260 if (size
< kMinSize
|| size
> kMaxSize
)
264 snprintf(label
, sizeof(label
), "%" B_PRId32
, size
);
266 BMessage
* message
= new BMessage(kMsgSetSize
);
267 message
->AddInt32("size", size
);
268 message
->AddString("name", Name());
270 BMenuItem
* item
= new BMenuItem(label
, message
);
271 if (size
== fCurrentFont
.Size())
272 item
->SetMarked(true);
274 fSizesMenu
->AddItem(item
);
280 FontSelectionView::_SelectCurrentFont(bool select
)
284 fCurrentFont
.GetFamilyAndStyle(&family
, &style
);
286 BMenuItem
*item
= fFontsMenu
->FindItem(family
);
288 item
->SetMarked(select
);
290 if (item
->Submenu() != NULL
) {
291 item
= item
->Submenu()->FindItem(style
);
293 item
->SetMarked(select
);
300 FontSelectionView::_SelectCurrentSize(bool select
)
303 snprintf(label
, sizeof(label
), "%" B_PRId32
, (int32
)fCurrentFont
.Size());
305 BMenuItem
* item
= fSizesMenu
->FindItem(label
);
307 item
->SetMarked(select
);
312 FontSelectionView::_UpdateFontPreview()
314 fPreviewText
->SetFont(&fCurrentFont
);
316 #ifdef INSTANT_UPDATE
323 FontSelectionView::_UpdateSystemFont()
327 fCurrentFont
.GetFamilyAndStyle(&family
, &style
);
329 if (strcmp(Name(), "menu") == 0) {
330 // The menu font is not handled as a system font
332 get_menu_info(&info
);
334 strlcpy(info
.f_family
, (const char*)family
, B_FONT_FAMILY_LENGTH
);
335 strlcpy(info
.f_style
, (const char*)style
, B_FONT_STYLE_LENGTH
);
336 info
.font_size
= fCurrentFont
.Size();
338 set_menu_info(&info
);
340 _set_system_font_(Name(), family
, style
, fCurrentFont
.Size());
345 FontSelectionView::SetDefaults()
350 const char* fontName
;
352 if (strcmp(Name(), "menu") == 0)
357 if (_get_system_default_font_(fontName
, family
, style
, &size
) != B_OK
) {
363 defaultFont
.SetFamilyAndStyle(family
, style
);
364 defaultFont
.SetSize(size
);
366 if (defaultFont
== fCurrentFont
)
369 _SelectCurrentFont(false);
371 fCurrentFont
= defaultFont
;
372 _UpdateFontPreview();
374 _SelectCurrentFont(true);
375 _SelectCurrentSize(true);
380 FontSelectionView::Revert()
385 _SelectCurrentFont(false);
387 fCurrentFont
= fSavedFont
;
388 _UpdateFontPreview();
390 _SelectCurrentFont(true);
391 _SelectCurrentSize(true);
396 FontSelectionView::IsDefaultable()
398 font_family defaultFamily
;
399 font_style defaultStyle
;
401 const char* fontName
;
403 if (strcmp(Name(), "menu") == 0)
408 if (_get_system_default_font_(fontName
, defaultFamily
, defaultStyle
,
409 &defaultSize
) != B_OK
) {
413 font_family currentFamily
;
414 font_style currentStyle
;
417 fCurrentFont
.GetFamilyAndStyle(¤tFamily
, ¤tStyle
);
418 currentSize
= fCurrentFont
.Size();
420 return strcmp(currentFamily
, defaultFamily
) != 0
421 || strcmp(currentStyle
, defaultStyle
) != 0
422 || currentSize
!= defaultSize
;
427 FontSelectionView::IsRevertable()
429 return fCurrentFont
!= fSavedFont
;
434 FontSelectionView::UpdateFontsMenu()
436 int32 numFamilies
= count_font_families();
438 fFontsMenu
->RemoveItems(0, fFontsMenu
->CountItems(), true);
440 fFontsMenu
->GetFont(&font
);
442 font_family currentFamily
;
443 font_style currentStyle
;
444 fCurrentFont
.GetFamilyAndStyle(¤tFamily
, ¤tStyle
);
446 for (int32 i
= 0; i
< numFamilies
; i
++) {
449 if (get_font_family(i
, &family
, &flags
) != B_OK
)
452 // if we're setting the fixed font, we only want to show fixed fonts
453 if (!strcmp(Name(), "fixed") && (flags
& B_IS_FIXED
) == 0)
456 float width
= font
.StringWidth(family
);
457 if (width
> fMaxFontNameWidth
)
458 fMaxFontNameWidth
= width
;
460 BMenu
* stylesMenu
= new BMenu(family
);
461 stylesMenu
->SetRadioMode(true);
462 stylesMenu
->SetFont(&font
);
464 BMessage
* message
= new BMessage(kMsgSetFamily
);
465 message
->AddString("family", family
);
466 message
->AddString("name", Name());
468 BMenuItem
* familyItem
= new BMenuItem(stylesMenu
, message
);
469 fFontsMenu
->AddItem(familyItem
);
471 int32 numStyles
= count_font_styles(family
);
473 for (int32 j
= 0; j
< numStyles
; j
++) {
475 if (get_font_style(family
, j
, &style
, &flags
) != B_OK
)
478 message
= new BMessage(kMsgSetStyle
);
479 message
->AddString("family", (char*)family
);
480 message
->AddString("style", (char*)style
);
481 message
->AddString("name", Name());
483 BMenuItem
*item
= new BMenuItem(style
, message
);
485 if (!strcmp(style
, currentStyle
)
486 && !strcmp(family
, currentFamily
)) {
487 item
->SetMarked(true);
488 familyItem
->SetMarked(true);
490 stylesMenu
->AddItem(item
);
493 stylesMenu
->SetTargetForItems(fMessageTarget
);
496 fFontsMenu
->SetTargetForItems(fMessageTarget
);