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
21static const uint32 kMsgMenuFontChange = 'mMFC';
22
23static int
24compare_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
33VirtualKeyboardWindow::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->SetKeymap(&fCurrentKeymap);
65
66	AddChild(BGroupLayoutBuilder(B_VERTICAL)
67		.Add(fKeyboardView));
68}
69
70
71void
72VirtualKeyboardWindow::_LoadLayouts(BMenu* menu)
73{
74	directory_which dataDirectories[] = {
75		B_USER_NONPACKAGED_DATA_DIRECTORY,
76		B_USER_DATA_DIRECTORY,
77		B_SYSTEM_NONPACKAGED_DIRECTORY,
78		B_SYSTEM_DATA_DIRECTORY,
79	};
80
81	for (uint i = 0; i < sizeof(dataDirectories)/sizeof(directory_which); i++) {
82		BPath path;
83		if (find_directory(dataDirectories[i], &path) != B_OK)
84			continue;
85
86		path.Append("KeyboardLayouts");
87
88		BDirectory directory;
89		if (directory.SetTo(path.Path()) == B_OK)
90			_LoadLayoutMenu(menu, directory);
91	}
92}
93
94
95void
96VirtualKeyboardWindow::_LoadLayoutMenu(BMenu* menu, BDirectory directory)
97{
98	entry_ref ref;
99
100	while (directory.GetNextRef(&ref) == B_OK) {
101		if (menu->FindItem(ref.name) != NULL)
102			continue;
103
104		BDirectory subdirectory;
105		subdirectory.SetTo(&ref);
106		if (subdirectory.InitCheck() == B_OK) {
107			BMenu* submenu = new BMenu(ref.name);
108			_LoadLayoutMenu(submenu, subdirectory);
109			menu->AddItem(submenu);
110		} else {
111			//BMessage* message = new BMessage(kChangeKeyboardLayout);
112			//message->AddRed("ref",&ref);
113			menu->AddItem(new BMenuItem(ref.name, NULL));
114		}
115	}
116}
117
118
119void
120VirtualKeyboardWindow::_LoadMaps()
121{
122	BPath path;
123	if (find_directory(B_SYSTEM_DATA_DIRECTORY, &path) != B_OK)
124		return;
125
126	path.Append("Keymaps");
127	BDirectory directory;
128	entry_ref ref;
129
130	if (directory.SetTo(path.Path()) == B_OK) {
131		while (directory.GetNextRef(&ref) == B_OK) {
132			fMapListView->AddItem(new KeymapListItem(ref));
133		}
134	}
135	fMapListView->SortItems(&compare_key_list_items);
136}
137
138
139void
140VirtualKeyboardWindow::_LoadFonts()
141{
142	int32 numFamilies = count_font_families();
143	font_family family, currentFamily;
144	font_style currentStyle;
145	uint32 flags;
146
147	be_plain_font->GetFamilyAndStyle(&currentFamily,&currentStyle);
148
149	for (int32 i = 0; i< numFamilies; i++) {
150		if (get_font_family(i, &family, &flags) == B_OK) {
151			BMenuItem* item = new BMenuItem(family, NULL);	//new BMessage(kMsgMenuFontChanged));
152			fFontMenu->AddItem(item);
153			if (!strcmp(family, currentFamily))
154				item->SetMarked(true);
155		}
156	}
157}
158
159
160void
161VirtualKeyboardWindow::MessageReceived(BMessage* message)
162{
163	BWindow::MessageReceived(message);
164}
165