/* * Copyright 2014 Freeman Lou * All rights reserved. Distributed under the terms of the MIT license. */ #include "VirtualKeyboardWindow.h" #include #include #include #include #include #include #include #include #include #include #include "KeyboardLayoutView.h" #include "KeymapListItem.h" static const uint32 kMsgMenuFontChange = 'mMFC'; static int compare_key_list_items(const void* a, const void* b) { KeymapListItem* item1 = *(KeymapListItem**)a; KeymapListItem* item2 = *(KeymapListItem**)b; return BLocale::Default()->StringCompare(item1->Text(), item2->Text()); } VirtualKeyboardWindow::VirtualKeyboardWindow(BInputServerDevice* dev) : BWindow(BRect(0, 0, 0, 0), "Virtual Keyboard", B_NO_BORDER_WINDOW_LOOK, B_FLOATING_ALL_WINDOW_FEEL, B_WILL_ACCEPT_FIRST_CLICK | B_AVOID_FOCUS), fDevice(dev) { BScreen screen; BRect screenRect(screen.Frame()); ScreenChanged(screenRect, screen.ColorSpace()); SetLayout(new BGroupLayout(B_VERTICAL)); // Add to an options window later, use as list for now fMapListView = new BListView("Maps"); fFontMenu = new BMenu("Font"); fLayoutMenu = new BMenu("Layout"); _LoadMaps(); _LoadLayouts(fLayoutMenu); _LoadFonts(); fCurrentKeymap.SetToCurrent(); fKeyboardView = new KeyboardLayoutView("Keyboard", fDevice); fKeyboardView->GetKeyboardLayout()->SetDefault(); fKeyboardView->SetKeymap(&fCurrentKeymap); AddChild(BGroupLayoutBuilder(B_VERTICAL).Add(fKeyboardView)); } void VirtualKeyboardWindow::_LoadLayouts(BMenu* menu) { directory_which dataDirectories[] = { B_USER_NONPACKAGED_DATA_DIRECTORY, B_USER_DATA_DIRECTORY, B_SYSTEM_NONPACKAGED_DIRECTORY, B_SYSTEM_DATA_DIRECTORY, }; for (uint i = 0; i < sizeof(dataDirectories) / sizeof(directory_which); i++) { BPath path; if (find_directory(dataDirectories[i], &path) != B_OK) continue; path.Append("KeyboardLayouts"); BDirectory directory; if (directory.SetTo(path.Path()) == B_OK) _LoadLayoutMenu(menu, directory); } } void VirtualKeyboardWindow::_LoadLayoutMenu(BMenu* menu, BDirectory directory) { entry_ref ref; while (directory.GetNextRef(&ref) == B_OK) { if (menu->FindItem(ref.name) != NULL) continue; BDirectory subdirectory; subdirectory.SetTo(&ref); if (subdirectory.InitCheck() == B_OK) { BMenu* submenu = new BMenu(ref.name); _LoadLayoutMenu(submenu, subdirectory); menu->AddItem(submenu); } else { // BMessage* message = new BMessage(kChangeKeyboardLayout); // message->AddRed("ref",&ref); menu->AddItem(new BMenuItem(ref.name, NULL)); } } } void VirtualKeyboardWindow::_LoadMaps() { BPath path; if (find_directory(B_SYSTEM_DATA_DIRECTORY, &path) != B_OK) return; path.Append("Keymaps"); BDirectory directory; entry_ref ref; if (directory.SetTo(path.Path()) == B_OK) { while (directory.GetNextRef(&ref) == B_OK) { fMapListView->AddItem(new KeymapListItem(ref)); } } fMapListView->SortItems(&compare_key_list_items); } void VirtualKeyboardWindow::_LoadFonts() { int32 numFamilies = count_font_families(); font_family family, currentFamily; font_style currentStyle; uint32 flags; be_plain_font->GetFamilyAndStyle(¤tFamily, ¤tStyle); for (int32 i = 0; i < numFamilies; i++) { if (get_font_family(i, &family, &flags) == B_OK) { BMenuItem* item = new BMenuItem(family, NULL); // new BMessage(kMsgMenuFontChanged)); fFontMenu->AddItem(item); if (!strcmp(family, currentFamily)) item->SetMarked(true); } } } void VirtualKeyboardWindow::MessageReceived(BMessage* message) { if (message->what == kKeymapChange) { fCurrentKeymap.SetToCurrent(); fKeyboardView->SetKeymap(&fCurrentKeymap); } BWindow::MessageReceived(message); } void VirtualKeyboardWindow::ScreenChanged(BRect screenRect, color_space depth) { ResizeTo(screenRect.Width(), screenRect.Height() / 3); MoveTo(0, screenRect.Height() - screenRect.Height() / 3); }