1#include "FontMenu.h"
2#include <Message.h>
3#include <MenuItem.h>
4#include <stdlib.h>
5
6	FontMenu::FontMenu()
7		: BMenu("", B_ITEMS_IN_COLUMN)
8	{
9		get_menu_info(&info);
10		SetRadioMode(true);
11		GetFonts();
12	}
13
14	FontMenu::~FontMenu()
15	{ /*nothing to clean up*/}
16
17	void
18	FontMenu::GetFonts()
19	{
20		int32 numFamilies = count_font_families();
21		for ( int32 i = 0; i < numFamilies; i++ ) {
22			font_family *family = (font_family*)malloc(sizeof(font_family));
23			uint32 flags;
24			if ( get_font_family(i, family, &flags) == B_OK ) {
25				fontStyleMenu = new BMenu(*family, B_ITEMS_IN_COLUMN);
26				fontStyleMenu->SetRadioMode(true);
27				int32 numStyles = count_font_styles(*family);
28				for ( int32 j = 0; j < numStyles; j++ ) {
29					font_style *style = (font_style*)malloc(sizeof(font_style));
30					if ( get_font_style(*family, j, style, &flags) == B_OK ) {
31						BMessage *msg = new BMessage(MENU_FONT_STYLE);
32						msg->AddPointer("family", family);
33						msg->AddPointer("style", style);
34						fontStyleItem = new BMenuItem(*style, msg, 0, 0);
35						fontStyleMenu->AddItem(fontStyleItem);
36					}
37				}
38				BMessage *msg = new BMessage(MENU_FONT_FAMILY);
39				msg->AddPointer("family", family);
40				font_style *style = (font_style*)malloc(sizeof(font_style));
41				// if font family selected, we need to change style to
42				// first style
43				if ( get_font_style(*family, 0, style, &flags) == B_OK )
44					msg->AddPointer("style", style);
45				fontFamily = new BMenuItem(fontStyleMenu, msg);
46				AddItem(fontFamily);
47			}
48		}
49	}
50
51	void
52	FontMenu::Update()
53	{
54		// it may be better to pull all menu prefs
55		// related stuff out of the FontMenu class
56		// so it can be easily reused in other apps
57		get_menu_info(&info);
58
59		// font menu
60		BFont font;
61 		font.SetFamilyAndStyle(info.f_family, info.f_style);
62 		font.SetSize(info.font_size);
63 		SetFont(&font);
64 		SetViewColor(info.background_color);
65		InvalidateLayout();
66
67		// font style menus
68 		for (int i = 0; i < CountItems(); i++) {
69 			ItemAt(i)->Submenu()->SetFont(&font);
70		}
71
72		ClearAllMarkedItems();
73		PlaceCheckMarkOnFont(info.f_family, info.f_style);
74	}
75
76	status_t
77	FontMenu::PlaceCheckMarkOnFont(font_family family, font_style style)
78	{
79		BMenuItem *fontFamilyItem;
80		BMenuItem *fontStyleItem;
81		BMenu *styleMenu;
82
83		fontFamilyItem = FindItem(family);
84
85		if ((fontFamilyItem != NULL) && (family != NULL))
86		{
87			fontFamilyItem->SetMarked(true);
88			styleMenu = fontFamilyItem->Submenu();
89
90			if ((styleMenu != NULL) && (style != NULL))
91			{
92				fontStyleItem = styleMenu->FindItem(style);
93
94				if (fontStyleItem != NULL)
95				{
96					fontStyleItem->SetMarked(true);
97				}
98
99			}
100			else
101				return B_ERROR;
102		}
103		else
104			return B_ERROR;
105
106
107		return B_OK;
108	}
109
110	void
111	FontMenu::ClearAllMarkedItems()
112	{
113		// we need to clear all menuitems and submenuitems
114		for (int i = 0; i < CountItems(); i++) {
115			ItemAt(i)->SetMarked(false);
116
117			BMenu *submenu = ItemAt(i)->Submenu();
118			for (int j = 0; j < submenu->CountItems(); j++) {
119				submenu->ItemAt(j)->SetMarked(false);
120			}
121		}
122
123	}
124