PrefFont.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /*
  2. * The contents of this file are subject to the Mozilla Public
  3. * License Version 1.1 (the "License"); you may not use this file
  4. * except in compliance with the License. You may obtain a copy of
  5. * the License at http://www.mozilla.org/MPL/
  6. *
  7. * Software distributed under the License is distributed on an "AS
  8. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9. * implied. See the License for the specific language governing
  10. * rights and limitations under the License.
  11. *
  12. * The Original Code is Vision.
  13. *
  14. * The Initial Developer of the Original Code is The Vision Team.
  15. * Portions created by The Vision Team are
  16. * Copyright (C) 1999, 2000, 2001 The Vision Team. All Rights
  17. * Reserved.
  18. *
  19. * Contributor(s): Rene Gollent
  20. * Todd Lair
  21. */
  22. #include "PrefFont.h"
  23. #include "Vision.h"
  24. #include <ctype.h>
  25. #include <stdlib.h>
  26. #include <ScrollView.h>
  27. #include <Menu.h>
  28. #include <MenuBar.h>
  29. #include <MenuField.h>
  30. #include <MenuItem.h>
  31. #include "NumericFilter.h"
  32. #include "VTextControl.h"
  33. struct FontStat
  34. {
  35. font_family family;
  36. int32 style_count;
  37. font_style *styles;
  38. };
  39. class FontMenuItem : public BMenuItem
  40. {
  41. public:
  42. FontMenuItem (const char *, const char *, BMessage *);
  43. FontMenuItem (const char *, const char *, BMenu *, BMessage* = NULL);
  44. virtual ~FontMenuItem (void);
  45. virtual void DrawContent (void);
  46. private:
  47. const char *fontName;
  48. const char *fontStyle;
  49. BFont myFont;
  50. };
  51. FontMenuItem::FontMenuItem (const char *font, const char *style, BMessage *msg)
  52. : BMenuItem (style, msg),
  53. fontName (font),
  54. fontStyle (style)
  55. {
  56. myFont.SetFamilyAndStyle (font, style);
  57. }
  58. FontMenuItem::FontMenuItem (const char *font, const char *style, BMenu *menu, BMessage *msg)
  59. : BMenuItem (menu, msg),
  60. fontName (font),
  61. fontStyle (style)
  62. {
  63. myFont.SetFamilyAndStyle (font, style);
  64. }
  65. FontMenuItem::~FontMenuItem (void)
  66. {
  67. }
  68. void
  69. FontMenuItem::DrawContent (void)
  70. {
  71. BMenu *menu (Menu());
  72. if (menu)
  73. menu->SetFont (&myFont, B_FONT_FAMILY_AND_STYLE);
  74. BMenuItem::DrawContent();
  75. }
  76. class FontMenu : public BMenu
  77. {
  78. public:
  79. FontMenu (const char *);
  80. virtual ~FontMenu (void);
  81. virtual void AttachedToWindow (void);
  82. };
  83. FontMenu::FontMenu (const char *name)
  84. : BMenu (name)
  85. {
  86. if (CountItems() == 0)
  87. {
  88. int32 i, family_count (count_font_families());
  89. FontStat *font_stat = new FontStat [family_count];
  90. for (i = 0; i < family_count; ++i)
  91. {
  92. uint32 flags;
  93. *font_stat[i].family = '\0';
  94. font_stat[i].style_count = 0;
  95. font_stat[i].styles = 0;
  96. if (get_font_family (i, &font_stat[i].family, &flags) == B_OK
  97. && (font_stat[i].style_count = count_font_styles (font_stat[i].family)) > 0)
  98. {
  99. font_stat[i].styles = new font_style [font_stat[i].style_count];
  100. for (int32 j = 0; j < font_stat[i].style_count; ++j)
  101. {
  102. *font_stat[i].styles[j] = '\0';
  103. get_font_style (font_stat[i].family, j, font_stat[i].styles + j, &flags);
  104. }
  105. }
  106. }
  107. int32 j;
  108. for (j = 0; j < family_count; ++j)
  109. if (*font_stat[j].family && font_stat[j].style_count)
  110. {
  111. BMenu *menu (new BMenu (font_stat[j].family));
  112. FontMenuItem *fontMenu (new FontMenuItem (font_stat[j].family, "", menu));
  113. AddItem (fontMenu);
  114. for (int32 k = 0; k < font_stat[j].style_count; ++k)
  115. {
  116. BMessage *msg (new BMessage (M_FONT_CHANGE));
  117. FontMenuItem *item;
  118. msg->AddString ("family", font_stat[j].family);
  119. msg->AddString ("style", font_stat[j].styles[k]);
  120. msg->AddInt32 ("which", i);
  121. menu->AddItem (item = new FontMenuItem (font_stat[j].family, font_stat[j].styles[k], msg));
  122. }
  123. }
  124. for (i = 0; i < family_count; ++i)
  125. delete [] font_stat[i].styles;
  126. delete [] font_stat;
  127. }
  128. }
  129. FontMenu::~FontMenu()
  130. {
  131. }
  132. void
  133. FontMenu::AttachedToWindow (void)
  134. {
  135. BMenu::AttachedToWindow();
  136. }
  137. static const char *FontControlLabels[] =
  138. {
  139. S_PREFFONT_TEXT,
  140. S_PREFFONT_SMESSAGES,
  141. S_PREFFONT_URLS,
  142. S_PREFFONT_NAMESLIST,
  143. S_PREFFONT_INPUT_TEXT,
  144. S_PREFFONT_WINLIST,
  145. S_PREFFONT_CHANLIST,
  146. S_PREFFONT_TSTAMP,
  147. 0
  148. };
  149. FontPrefsView::FontPrefsView (BRect frame)
  150. : BView (frame, "Font prefs", B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FRAME_EVENTS),
  151. fFontMenuField (NULL),
  152. fFontElementField (NULL),
  153. fActiveFont (0)
  154. {
  155. SetViewColor (ui_color (B_PANEL_BACKGROUND_COLOR));
  156. BMenu *fElementMenu (new BMenu ("elements"));
  157. for (int32 i = 0; FontControlLabels[i]; i++)
  158. {
  159. BMessage *msg (new BMessage (M_FONT_ELEMENT_CHANGE));
  160. msg->AddInt32 ("index", i);
  161. fElementMenu->AddItem (new BMenuItem (FontControlLabels[i], msg));
  162. }
  163. fFontElementField = new BMenuField (BRect (10, 10, 200, 50), "elements", "Element: ",
  164. fElementMenu);
  165. AddChild (fFontElementField);
  166. FontMenu *menu (new FontMenu ("fonts"));
  167. fFontMenuField = new BMenuField (BRect (10, 10, 200, 50), "fonts", S_PREFFONT_FONTLABEL, menu);
  168. AddChild (fFontMenuField);
  169. fTextControl = new VTextControl (BRect (60, 60, 200, 90), "", S_PREFFONT_SIZELABEL, "",
  170. new BMessage (M_FONT_SIZE_CHANGE));
  171. fTextControl->TextView()->AddFilter (new NumericFilter());
  172. AddChild (fTextControl);
  173. }
  174. FontPrefsView::~FontPrefsView (void)
  175. {
  176. }
  177. void
  178. FontPrefsView::AttachedToWindow (void)
  179. {
  180. BView::AttachedToWindow ();
  181. }
  182. void
  183. FontPrefsView::AllAttached (void)
  184. {
  185. BView::AllAttached ();
  186. fFontElementField->SetDivider (fFontElementField->StringWidth(
  187. fFontElementField->Label()) + 5);
  188. fFontElementField->ResizeToPreferred();
  189. fFontMenuField->SetDivider (fFontMenuField->StringWidth (fFontMenuField->Label()) + 5);
  190. fFontMenuField->ResizeToPreferred();
  191. fTextControl->SetDivider (fTextControl->StringWidth (fTextControl->Label()) + 5);
  192. BMenu *menu (fFontElementField->Menu());
  193. fTextControl->SetTarget (this);
  194. menu->SetTargetForItems (this);
  195. menu->SetLabelFromMarked (true);
  196. BMenuItem *it (menu->ItemAt (0));
  197. if (it)
  198. dynamic_cast<BInvoker *>(it)->Invoke();
  199. BRect frame (fFontElementField->Frame());
  200. fFontMenuField->MoveTo (frame.left, frame.bottom + 20);
  201. menu = fFontMenuField->Menu();
  202. menu->SetTargetForItems (this);
  203. menu->SetLabelFromMarked (true);
  204. float width;
  205. float height;
  206. fFontMenuField->GetPreferredSize(&width, &height);
  207. fTextControl->ResizeToPreferred();
  208. fTextControl->MoveTo (fFontMenuField->Frame().right + width + 5,
  209. fFontMenuField->Frame().top);
  210. for (int32 i = 0; i < menu->CountItems(); i++)
  211. menu->ItemAt(i)->Submenu()->SetTargetForItems (this);
  212. const BFont *current (vision_app->GetClientFont (0));
  213. font_family family;
  214. font_style style;
  215. current->GetFamilyAndStyle (&family, &style);
  216. it = menu->FindItem (family);
  217. if (it)
  218. {
  219. it = it->Submenu()->FindItem (style);
  220. if (it)
  221. dynamic_cast<BInvoker *>(it)->Invoke();
  222. }
  223. }
  224. void
  225. FontPrefsView::FrameResized (float width, float height)
  226. {
  227. BView::FrameResized (width, height);
  228. }
  229. static inline void
  230. UnsetMarked (BMenuField *field)
  231. {
  232. BMenuItem *item;
  233. for (int32 i = 0; i < field->Menu()->CountItems(); ++i)
  234. {
  235. BMenu *menu (field->Menu()->SubmenuAt (i));
  236. if ((item = menu->FindMarked()) != 0)
  237. {
  238. item->SetMarked (false);
  239. break;
  240. }
  241. }
  242. }
  243. void
  244. FontPrefsView::MessageReceived (BMessage *msg)
  245. {
  246. switch (msg->what)
  247. {
  248. case M_FONT_CHANGE:
  249. {
  250. BMenuItem *item (NULL);
  251. const char *family (NULL);
  252. const char *style (NULL);
  253. UnsetMarked (fFontMenuField);
  254. msg->FindPointer ("source", reinterpret_cast<void **>(&item));
  255. item->SetMarked (true);
  256. msg->FindString ("family", &family);
  257. msg->FindString ("style", &style);
  258. vision_app->ClientFontFamilyAndStyle (fActiveFont, family, style);
  259. fFontMenuField->MenuItem()->SetLabel (family);
  260. }
  261. break;
  262. case M_FONT_SIZE_CHANGE:
  263. {
  264. const char *text (fTextControl->TextView()->Text());
  265. float size (atof (text));
  266. vision_app->ClientFontSize (fActiveFont, size);
  267. }
  268. break;
  269. case M_FONT_ELEMENT_CHANGE:
  270. {
  271. fActiveFont = msg->FindInt32 ("index");
  272. UnsetMarked (fFontMenuField);
  273. const BFont *font (vision_app->GetClientFont (fActiveFont));
  274. font_family family;
  275. font_style style;
  276. font->GetFamilyAndStyle (&family, &style);
  277. char line[100];
  278. memset (line, 0, sizeof(line));
  279. sprintf(line, "%ld", (long)(font->Size()));
  280. fTextControl->TextView()->SetText (line);
  281. BMenuItem *it = fFontMenuField->Menu()->FindItem (family);
  282. if (it)
  283. {
  284. it = it->Submenu()->FindItem (style);
  285. if (it)
  286. it->SetMarked (true);
  287. }
  288. fFontMenuField->MenuItem()->SetLabel (family);
  289. }
  290. break;
  291. default:
  292. BView::MessageReceived (msg);
  293. }
  294. }