diff --git a/src/prefs/appearance/FontMenu.cpp b/src/prefs/appearance/FontMenu.cpp new file mode 100644 index 0000000000..9ec4771375 --- /dev/null +++ b/src/prefs/appearance/FontMenu.cpp @@ -0,0 +1,123 @@ +#include "FontMenu.h" +#include +#include +#include + + FontMenu::FontMenu() + : BMenu("", B_ITEMS_IN_COLUMN) + { + get_menu_info(&info); + SetRadioMode(true); + GetFonts(); + } + + FontMenu::~FontMenu() + { /*nothing to clean up*/} + + void + FontMenu::GetFonts() + { + int32 numFamilies = count_font_families(); + for ( int32 i = 0; i < numFamilies; i++ ) { + font_family *family = (font_family*)malloc(sizeof(font_family)); + uint32 flags; + if ( get_font_family(i, family, &flags) == B_OK ) { + fontStyleMenu = new BMenu(*family, B_ITEMS_IN_COLUMN); + fontStyleMenu->SetRadioMode(true); + int32 numStyles = count_font_styles(*family); + for ( int32 j = 0; j < numStyles; j++ ) { + font_style *style = (font_style*)malloc(sizeof(font_style)); + if ( get_font_style(*family, j, style, &flags) == B_OK ) { + BMessage *msg = new BMessage(MENU_FONT_STYLE); + msg->AddPointer("family", family); + msg->AddPointer("style", style); + fontStyleItem = new BMenuItem(*style, msg, 0, 0); + fontStyleMenu->AddItem(fontStyleItem); + } + } + BMessage *msg = new BMessage(MENU_FONT_FAMILY); + msg->AddPointer("family", family); + font_style *style = (font_style*)malloc(sizeof(font_style)); + // if font family selected, we need to change style to + // first style + if ( get_font_style(*family, 0, style, &flags) == B_OK ) + msg->AddPointer("style", style); + fontFamily = new BMenuItem(fontStyleMenu, msg); + AddItem(fontFamily); + } + } + } + + void + FontMenu::Update() + { + // it may be better to pull all menu prefs + // related stuff out of the FontMenu class + // so it can be easily reused in other apps + get_menu_info(&info); + + // font menu + BFont font; + font.SetFamilyAndStyle(info.f_family, info.f_style); + font.SetSize(info.font_size); + SetFont(&font); + SetViewColor(info.background_color); + InvalidateLayout(); + + // font style menus + for (int i = 0; i < CountItems(); i++) { + ItemAt(i)->Submenu()->SetFont(&font); + } + + ClearAllMarkedItems(); + PlaceCheckMarkOnFont(info.f_family, info.f_style); + } + + status_t + FontMenu::PlaceCheckMarkOnFont(font_family family, font_style style) + { + BMenuItem *fontFamilyItem; + BMenuItem *fontStyleItem; + BMenu *styleMenu; + + fontFamilyItem = FindItem(family); + + if ((fontFamilyItem != NULL) && (family != NULL)) + { + fontFamilyItem->SetMarked(true); + styleMenu = fontFamilyItem->Submenu(); + + if ((styleMenu != NULL) && (style != NULL)) + { + fontStyleItem = styleMenu->FindItem(style); + + if (fontStyleItem != NULL) + { + fontStyleItem->SetMarked(true); + } + + } + else + return B_ERROR; + } + else + return B_ERROR; + + + return B_OK; + } + + void + FontMenu::ClearAllMarkedItems() + { + // we need to clear all menuitems and submenuitems + for (int i = 0; i < CountItems(); i++) { + ItemAt(i)->SetMarked(false); + + BMenu *submenu = ItemAt(i)->Submenu(); + for (int j = 0; j < submenu->CountItems(); j++) { + submenu->ItemAt(j)->SetMarked(false); + } + } + + } diff --git a/src/prefs/appearance/FontMenu.h b/src/prefs/appearance/FontMenu.h new file mode 100644 index 0000000000..e57b2f9580 --- /dev/null +++ b/src/prefs/appearance/FontMenu.h @@ -0,0 +1,23 @@ +#ifndef FONTMENU_H_ +#define FONTMENU_H_ + +#include + +#define MENU_FONT_STYLE 'mnfs' +#define MENU_FONT_FAMILY 'mnff' + +class FontMenu : public BMenu { +public: + FontMenu(); + virtual ~FontMenu(); + virtual void GetFonts(); + virtual void Update(); + virtual status_t PlaceCheckMarkOnFont(font_family family, font_style style); + virtual void ClearAllMarkedItems(); + + menu_info info; + BMenuItem *fontFamily; + BMenu *fontStyleMenu; + BMenuItem *fontStyleItem; +}; +#endif diff --git a/src/prefs/appearance/Jamfile b/src/prefs/appearance/Jamfile index b157a1d302..7bb2dfcf6a 100644 --- a/src/prefs/appearance/Jamfile +++ b/src/prefs/appearance/Jamfile @@ -10,6 +10,8 @@ Preference Appearance : APRWindow.cpp CurView.cpp DecView.cpp + FontMenu.cpp + MenuView.cpp PreviewDriver.cpp # SysCursorAPI.cpp ColorWell.cpp diff --git a/src/prefs/appearance/MenuView.cpp b/src/prefs/appearance/MenuView.cpp new file mode 100644 index 0000000000..1ec68b17e2 --- /dev/null +++ b/src/prefs/appearance/MenuView.cpp @@ -0,0 +1,351 @@ +#include "MenuView.h" +#include +#include +#include +#include + +#define TOGGLE_TRIGGERS 'tgtr' +#define ALT_COMMAND 'acmd' +#define CTRL_COMMAND 'ccmd' +#define SET_FONT_SIZE 'sfsz' +#define SET_DEFAULTS 'sdef' +#define REVERT_SETTINGS 'rvst' + +MenuView::MenuView(BRect frame, const char *name, int32 resize, int32 flags) + : BView(frame,name, resize, flags) +{ + SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + get_menu_info(&menuinfo); + revertinfo=menuinfo; + revert=false; + + fontmenu=new FontMenu; + fontmenu->SetLabelFromMarked(true); + fontmenu->GetFonts(); + fontmenu->Update(); + + fontsizemenu=new BMenu(""); + fontsizemenu->SetLabelFromMarked(true); + + BMenuItem *item; + BMessage *msg; + + msg=new BMessage(SET_FONT_SIZE); + msg->AddInt32("size",10); + item=new BMenuItem("10",msg); + fontsizemenu->AddItem(item); + + msg=new BMessage(SET_FONT_SIZE); + msg->AddInt32("size",11); + item=new BMenuItem("11",msg); + fontsizemenu->AddItem(item); + + msg=new BMessage(SET_FONT_SIZE); + msg->AddInt32("size",12); + item=new BMenuItem("12",msg); + fontsizemenu->AddItem(item); + + msg=new BMessage(SET_FONT_SIZE); + msg->AddInt32("size",14); + item=new BMenuItem("14",msg); + fontsizemenu->AddItem(item); + + msg=new BMessage(SET_FONT_SIZE); + msg->AddInt32("size",18); + item=new BMenuItem("18",msg); + fontsizemenu->AddItem(item); + + msg=new BMessage(SET_FONT_SIZE); + msg->AddInt32("size",20); + item=new BMenuItem("20",msg); + fontsizemenu->AddItem(item); + + msg=new BMessage(SET_FONT_SIZE); + msg->AddInt32("size",22); + item=new BMenuItem("22",msg); + fontsizemenu->AddItem(item); + + msg=new BMessage(SET_FONT_SIZE); + msg->AddInt32("size",24); + item=new BMenuItem("24",msg); + fontsizemenu->AddItem(item); + + switch((int32)menuinfo.font_size) + { + case 10: + { + item=fontsizemenu->FindItem("10"); + break; + } + case 11: + { + item=fontsizemenu->FindItem("11"); + break; + } + case 12: + { + item=fontsizemenu->FindItem("12"); + break; + } + case 14: + { + item=fontsizemenu->FindItem("14"); + break; + } + case 18: + { + item=fontsizemenu->FindItem("18"); + break; + } + case 20: + { + item=fontsizemenu->FindItem("20"); + break; + } + case 22: + { + item=fontsizemenu->FindItem("22"); + break; + } + case 24: + { + item=fontsizemenu->FindItem("24"); + break; + } + default: + { + char fontsizestr[10]; + sprintf(fontsizestr,"%ld",(int32) menuinfo.font_size); + msg=new BMessage(SET_FONT_SIZE); + msg->AddInt32("size",(int32)menuinfo.font_size); + item=new BMenuItem(fontsizestr,msg); + fontsizemenu->AddItem(item); + break; + } + } + item->SetMarked(true); + + + BRect r(10,10,210,40); + r.OffsetTo((Bounds().Width()-r.Width())/2,10); + fontfield=new BMenuField(r,"fontfield","",fontmenu); + fontfield->SetLabel("Font:"); + fontfield->SetDivider(StringWidth("Font:")+5); + AddChild(fontfield); + + r.OffsetTo((Bounds().Width()-r.Width())/2,fontfield->Frame().bottom+10); + fontsizefield=new BMenuField(r,"fontsizefield","",fontsizemenu); + fontsizefield->SetLabel("Font Size:"); + fontsizefield->SetDivider(StringWidth("Font Size:")+5); + AddChild(fontsizefield); + + r.OffsetTo(10, fontsizefield->Frame().bottom + 10); + r.right+=20; + showtriggers=new BCheckBox(r, "showtriggers", "Always Show Triggers", + new BMessage(TOGGLE_TRIGGERS)); + showtriggers->ResizeToPreferred(); + showtriggers->MoveTo( (Bounds().Width()-showtriggers->Bounds().Width())/2, r.top); + AddChild(showtriggers); + if(menuinfo.triggers_always_shown) + showtriggers->SetValue(B_CONTROL_ON); + + r.bottom=r.top+75; + r.OffsetTo((Bounds().Width()-r.Width())/2,showtriggers->Frame().bottom+10); + BBox *radiobox=new BBox(r,"radiobox"); + radiobox->SetLabel("Shortcut Key"); + AddChild(radiobox); + + r.Set(10,20,50,30); + altcmd=new BRadioButton(r,"altcommand","Alt", new BMessage(ALT_COMMAND)); + altcmd->ResizeToPreferred(); + radiobox->AddChild(altcmd); + + r.OffsetBy(0,25); + ctrlcmd=new BRadioButton(r,"ctrlcommand","Control", new BMessage(CTRL_COMMAND)); + ctrlcmd->ResizeToPreferred(); + radiobox->AddChild(ctrlcmd); + + MarkCommandKey(); + revertaltcmd=altcommand; + + defaultsbutton=new BButton(r, "defaultsbutton", "Defaults", new BMessage(SET_DEFAULTS)); + defaultsbutton->ResizeToPreferred(); + + revertbutton=new BButton(r, "revertbutton", "Revert", new BMessage(REVERT_SETTINGS)); + revertbutton->ResizeToPreferred(); + + + defaultsbutton->MoveTo( (Bounds().Width()- + (defaultsbutton->Bounds().Width()+revertbutton->Bounds().Width()+10))/2, + radiobox->Frame().bottom+20); + revertbutton->MoveTo(defaultsbutton->Frame().right+10, radiobox->Frame().bottom+20); + + AddChild(defaultsbutton); + AddChild(revertbutton); + revertbutton->SetEnabled(false); + +} + +MenuView::~MenuView(void) +{ +} + +void MenuView::AttachedToWindow(void) +{ + for(int32 i=0; iCountItems(); i++) + { + BMenu *menu=fontmenu->SubmenuAt(i); + if(menu) + menu->SetTargetForItems(this); + } + fontmenu->SetTargetForItems(this); + fontsizemenu->SetTargetForItems(this); + showtriggers->SetTarget(this); + altcmd->SetTarget(this); + ctrlcmd->SetTarget(this); + defaultsbutton->SetTarget(this); + revertbutton->SetTarget(this); +} + +void MenuView::MessageReceived(BMessage *msg) +{ + switch(msg->what) + { + case B_MODIFIERS_CHANGED: + { + MarkCommandKey(); + break; + } + case MENU_FONT_FAMILY: + case MENU_FONT_STYLE: + { + if(!revert) + revertbutton->SetEnabled(true); + revert=true; + font_family *family; + msg->FindPointer("family", (void**)&family); + font_style *style; + msg->FindPointer("style", (void**)&style); + menuinfo.f_family = *family; + menuinfo.f_style = *style; + set_menu_info(&menuinfo); + + fontmenu->Update(); + break; + } + case SET_FONT_SIZE: + { + if(!revert) + revertbutton->SetEnabled(true); + revert=true; + int32 size; + msg->FindInt32("size", &size); + menuinfo.font_size = size; + set_menu_info(&menuinfo); + fontmenu->Update(); + break; + } + case ALT_COMMAND: + { + if(!revert) + revertbutton->SetEnabled(true); + revert=true; + altcommand=true; + SetCommandKey(altcommand); + break; + } + case CTRL_COMMAND: + { + if(!revert) + revertbutton->SetEnabled(true); + revert=true; + altcommand=false; + SetCommandKey(altcommand); + break; + } + case TOGGLE_TRIGGERS: + { + if(!revert) + revertbutton->SetEnabled(true); + revert=true; + menuinfo.triggers_always_shown=(showtriggers->Value()==B_CONTROL_ON); + set_menu_info(&menuinfo); + break; + } + case REVERT_SETTINGS: + { + revert=false; + revertbutton->SetEnabled(false); + SetCommandKey(revertaltcmd); + altcommand=revertaltcmd; + MarkCommandKey(); + menuinfo=revertinfo; + fontmenu->Update(); + showtriggers->SetValue( (menuinfo.triggers_always_shown)?B_CONTROL_ON:B_CONTROL_OFF); + set_menu_info(&revertinfo); + break; + } + case SET_DEFAULTS: + { + if(!revert) + revertbutton->SetEnabled(true); + revert=true; + + menuinfo.triggers_always_shown=false; + menuinfo.font_size=12.0; + sprintf(menuinfo.f_family,"%s","Swis721 BT"); + sprintf(menuinfo.f_style,"%s","Roman"); + set_menu_info(&menuinfo); + + fontmenu->Update(); + altcommand=true; + SetCommandKey(altcommand); + MarkCommandKey(); + showtriggers->SetValue( (menuinfo.triggers_always_shown)?B_CONTROL_ON:B_CONTROL_OFF); + break; + } + default: + BView::MessageReceived(msg); + break; + } +} + +void MenuView::MarkCommandKey(void) +{ + key_map *keys; + char *chars; + + get_key_map(&keys, &chars); + + altcommand=(keys->left_command_key==0x5d) && (keys->right_command_key==0x5f); + free(chars); + free(keys); + + if(altcommand) + altcmd->SetValue(B_CONTROL_ON); + else + ctrlcmd->SetValue(B_CONTROL_ON); +} + +void MenuView::SetCommandKey(bool use_alt) +{ + if(use_alt) + { + set_modifier_key(B_LEFT_COMMAND_KEY, 0x5d); + set_modifier_key(B_RIGHT_COMMAND_KEY, 0x5f); + set_modifier_key(B_LEFT_CONTROL_KEY, 0x5c); + set_modifier_key(B_RIGHT_OPTION_KEY, 0x60); + + be_roster->Broadcast(new BMessage(B_MODIFIERS_CHANGED)); + } + else + { + set_modifier_key(B_LEFT_COMMAND_KEY, 0x5c); + set_modifier_key(B_RIGHT_COMMAND_KEY, 0x60); + set_modifier_key(B_LEFT_CONTROL_KEY, 0x5d); + set_modifier_key(B_RIGHT_OPTION_KEY, 0x5f); + + be_roster->Broadcast(new BMessage(B_MODIFIERS_CHANGED)); + } +} diff --git a/src/prefs/appearance/MenuView.h b/src/prefs/appearance/MenuView.h new file mode 100644 index 0000000000..0d918c6ef6 --- /dev/null +++ b/src/prefs/appearance/MenuView.h @@ -0,0 +1,36 @@ +#ifndef MENUVIEW_H_ +#define MENUVIEW_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "FontMenu.h" + +class MenuView : public BView +{ +public: + MenuView(BRect frame, const char *name, int32 resize, int32 flags); + ~MenuView(void); + void AttachedToWindow(void); + void MessageReceived(BMessage *msg); + void MarkCommandKey(void); + void SetCommandKey(bool use_alt); +private: + BMenuField *fontfield, *fontsizefield; + BMenu *fontsizemenu; + FontMenu *fontmenu; + BButton *defaultsbutton, *revertbutton; + BCheckBox *showtriggers; + BRadioButton *altcmd, *ctrlcmd; + menu_info menuinfo,revertinfo; + bool altcommand; + bool revert, revertaltcmd; +}; + +#endif