xref: /haiku/src/add-ons/input_server/devices/virtualkeyboard/VirtualKeyboardWindow.cpp (revision 1deede7388b04dbeec5af85cae7164735ea9e70d)
1 /*
2  * Copyright 2014 Freeman Lou <freemanlou2430@yahoo.com>
3  * All rights reserved. Distributed under the terms of the MIT license.
4  */
5 #include "VirtualKeyboardWindow.h"
6 
7 #include <Directory.h>
8 #include <Entry.h>
9 #include <FindDirectory.h>
10 #include <GroupLayoutBuilder.h>
11 #include <ListView.h>
12 #include <Locale.h>
13 #include <Menu.h>
14 #include <MenuItem.h>
15 #include <Path.h>
16 #include <Screen.h>
17 
18 #include "KeyboardLayoutView.h"
19 #include "KeymapListItem.h"
20 
21 static const uint32 kMsgMenuFontChange = 'mMFC';
22 
23 static int
24 compare_key_list_items(const void* a, const void* b)
25 {
26 	KeymapListItem* item1 = *(KeymapListItem**)a;
27 	KeymapListItem* item2 = *(KeymapListItem**)b;
28 
29 	return BLocale::Default()->StringCompare(item1->Text(), item2->Text());
30 }
31 
32 
33 VirtualKeyboardWindow::VirtualKeyboardWindow(BInputServerDevice* dev)
34 	:
35 	BWindow(BRect(0,0,0,0),"Virtual Keyboard",
36 	B_NO_BORDER_WINDOW_LOOK, B_FLOATING_ALL_WINDOW_FEEL,
37 	B_WILL_ACCEPT_FIRST_CLICK | B_AVOID_FOCUS),
38 	fDevice(dev)
39 {
40 	BScreen screen;
41 	BRect screenRect(screen.Frame());
42 
43 	ResizeTo(screenRect.Width(), screenRect.Height() / 3);
44 	MoveTo(0,screenRect.Height() - screenRect.Height() / 3);
45 
46 	SetLayout(new BGroupLayout(B_VERTICAL));
47 
48 	//Add to an options window later, use as list for now
49 	fMapListView = new BListView("Maps");
50 	fFontMenu = new BMenu("Font");
51 	fLayoutMenu = new BMenu("Layout");
52 
53 	_LoadMaps();
54 	_LoadLayouts(fLayoutMenu);
55 	_LoadFonts();
56 
57 	KeymapListItem* current =
58 		static_cast<KeymapListItem*>(fMapListView->LastItem());
59 	fCurrentKeymap.Load(current->EntryRef());
60 
61 
62 	fKeyboardView = new KeyboardLayoutView("Keyboard",fDevice);
63 	fKeyboardView->GetKeyboardLayout()->SetDefault();
64 	fKeyboardView->SetEditable(false);
65 	fKeyboardView->SetKeymap(&fCurrentKeymap);
66 
67 	AddChild(BGroupLayoutBuilder(B_VERTICAL)
68 		.Add(fKeyboardView));
69 }
70 
71 
72 void
73 VirtualKeyboardWindow::_LoadLayouts(BMenu* menu)
74 {
75 	directory_which dataDirectories[] = {
76 		B_USER_NONPACKAGED_DATA_DIRECTORY,
77 		B_USER_DATA_DIRECTORY,
78 		B_SYSTEM_NONPACKAGED_DIRECTORY,
79 		B_SYSTEM_DATA_DIRECTORY,
80 	};
81 
82 	for (uint i = 0; i < sizeof(dataDirectories)/sizeof(directory_which); i++) {
83 		BPath path;
84 		if (find_directory(dataDirectories[i], &path) != B_OK)
85 			continue;
86 
87 		path.Append("KeyboardLayouts");
88 
89 		BDirectory directory;
90 		if (directory.SetTo(path.Path()) == B_OK)
91 			_LoadLayoutMenu(menu, directory);
92 	}
93 }
94 
95 
96 void
97 VirtualKeyboardWindow::_LoadLayoutMenu(BMenu* menu, BDirectory directory)
98 {
99 	entry_ref ref;
100 
101 	while (directory.GetNextRef(&ref) == B_OK) {
102 		if (menu->FindItem(ref.name) != NULL)
103 			continue;
104 
105 		BDirectory subdirectory;
106 		subdirectory.SetTo(&ref);
107 		if (subdirectory.InitCheck() == B_OK) {
108 			BMenu* submenu = new BMenu(ref.name);
109 			_LoadLayoutMenu(submenu, subdirectory);
110 			menu->AddItem(submenu);
111 		} else {
112 			//BMessage* message = new BMessage(kChangeKeyboardLayout);
113 			//message->AddRed("ref",&ref);
114 			menu->AddItem(new BMenuItem(ref.name, NULL));
115 		}
116 	}
117 }
118 
119 
120 void
121 VirtualKeyboardWindow::_LoadMaps()
122 {
123 	BPath path;
124 	if (find_directory(B_SYSTEM_DATA_DIRECTORY, &path) != B_OK)
125 		return;
126 
127 	path.Append("Keymaps");
128 	BDirectory directory;
129 	entry_ref ref;
130 
131 	if (directory.SetTo(path.Path()) == B_OK) {
132 		while (directory.GetNextRef(&ref) == B_OK) {
133 			fMapListView->AddItem(new KeymapListItem(ref));
134 		}
135 	}
136 	fMapListView->SortItems(&compare_key_list_items);
137 }
138 
139 
140 void
141 VirtualKeyboardWindow::_LoadFonts()
142 {
143 	int32 numFamilies = count_font_families();
144 	font_family family, currentFamily;
145 	font_style currentStyle;
146 	uint32 flags;
147 
148 	be_plain_font->GetFamilyAndStyle(&currentFamily,&currentStyle);
149 
150 	for (int32 i = 0; i< numFamilies; i++) {
151 		if (get_font_family(i, &family, &flags) == B_OK) {
152 			BMenuItem* item = new BMenuItem(family, NULL);	//new BMessage(kMsgMenuFontChanged));
153 			fFontMenu->AddItem(item);
154 			if (!strcmp(family, currentFamily))
155 				item->SetMarked(true);
156 		}
157 	}
158 }
159 
160 
161 void
162 VirtualKeyboardWindow::MessageReceived(BMessage* message)
163 {
164 	BWindow::MessageReceived(message);
165 }
166