суббота, 17 ноября 2007 г.

iphone?


Прочитал недавно статью про iphone. Какой он там весь удобный и все такое. Заразился идеей о управлении КПК (WM5) с помощью одной руки и даже одного пальца. Для меня это актуально, так как пользуюсь КПК в метро. Поменял часть софта - менеджер задач и лоунчер. А с клавиатурой пришлось повозится. Перепробовал много вариантов. PocketCM уовлетворила почти всем, кроме того, что была глючная и не давала сделать такую раскладку какую я хочу. И вот я случайно наткнулся на eurokbd. Программа интересная тем, что opensource (хоть и слегка кривовато написана, но да ладно, дареному коню... спасибо автору огромное!). Подправил для нее раскладку, перерисовал скины, подправил исходники и вот, что получилось.

Картинко 1
Картинко 2
Картинко 3
Картинко 4

Первое, что нужно было сделать - придумать раскладку. Раскладка должна была быть такой, чтобы легко попадать по клавишам большим пальцем моей руки (держа КПК той же рукой). Qwerty не подходит. Был соблазн набросать как придется новую раскладку, но это абсолютно не аправданно. Решил сгенерировать оптимальный вариант с учетом частоты следования букв друг за другом. Написал на perl анализатор текста на входе которого текст, на выходе описание для graphwiz (буква -> буква [вес]). Вес являлся частотой появления комбинации букв. На основе такого описания graphwiz построил графики, расположив узлы таким образом, чтобы расстояния между элементами с наибольшими весами было наименьшее. Таким образом минимизируется время набор слов. На графиках линии связей между буквами убраны для простоты картинки.

Инглиш
Русский

Далее нарисовал скины. А саму eurokbd пришлось пропатчить, чтобы она активную кнопку подсвечивала белым фоном (а не черным как это жестко вбито в исходниках), а также не выводила меню переключения раскладки, а переключала ее сразу же с rus на lat и с lat на rus). Итого получилась очень удобная клавиатура! Несмотря на то, что раскладка не qwerty - привыкаешь ОЧЕНЬ быстро. Я уже не могу на стандартную мелкую смотреть без тошноты.

http://toril.ru/pda/eukbak.zip

Для интересующихся, скрипт на perl для анализа текста (textanal.pl):

#!/usr/bin/perl
# Akshaal (C) 2007

# Creates dot graph for link between characters

use warnings;
use strict;

use utf8;
use encoding 'utf8';

my %ass;
my $prev;

my %allow;
for (split '', "йцукенгшщзхъфывапролджэячсмитьбюё ") {
$allow{$_} = 1;
};

sub add ($) {
my $c = shift;

if (defined $prev) {
if (ord($prev) > ord($c)) {
$ass{"$prev$c"} ++;
} else {
$ass{"$c$prev"} ++;
}
}

$prev = $c;
}

# Calc weights
while (<>) {
chop;
for my $c (split '') {
$c = lc $c;

unless ($allow{$c}) {
$c = ' ';
}

add ($c);
}
add (' ');
}

# Create dot
print "graph D {\n";
for my $link (keys %ass) {
my $weight = $ass {$link};
my $a = substr $link, 0, 1;
my $b = substr $link, 1, 1;

print " \"$a\" -- \"$b\" [weight=$weight, style=invis];\n";
}
print "}\n";


А это патч на eurokbd:

--- eurokbd.cpp.old 2007-10-11 20:45:00.000000000 +0300
+++ eurokbd.cpp 2007-11-17 17:58:48.000000000 +0200
@@ -369,10 +369,12 @@

if(vk==_VK_MOD)
{
- if( m_subkeyCurrent!=SUBKEY_PARENT )
- {
- LoadConfig(m_subkeyCurrent->data.pw);
- }
+ if(0==wcscmp(m_pwCurrentConfigName.ptr(), L"rus"))
+ {
+ LoadConfig(L"lat");
+ } else {
+ LoadConfig(L"rus");
+ }
} else if(vk==_VK_FN)
{
// } else if(vk==_VK_CUT)
@@ -788,8 +790,8 @@
COLORREF bgColor, fgColor;
if( m_subkeyCurrent==p )
{
- fgColor = RGB(0xFF,0xFF,0xFF);
- bgColor = RGB(0x00,0x00,0x00);
+ bgColor = RGB(0xFF,0xFF,0xFF);
+ fgColor = RGB(0x00,0x00,0x00);
} else
{
fgColor = m_config->m_colors[p->group][0];
@@ -832,8 +834,8 @@
COLORREF bgColor, fgColor;
if( m_subkeyCurrent==SUBKEY_PARENT )
{
- fgColor = RGB(0xFF,0xFF,0xFF);
- bgColor = RGB(0x00,0x00,0x00);
+ bgColor = RGB(0xFF,0xFF,0xFF);
+ fgColor = RGB(0x00,0x00,0x00);
} else
{
fgColor = m_config->m_colors[m_keyCurrent->group][0];
@@ -987,43 +989,6 @@
}
if(m_hwndPop)
{
- // кнопка Mod
- if(m_keyCurrent->vk==_VK_MOD)
- {
- m_keyCurrent->subkeys.destroy();
-
- WIN32_FIND_DATA ffdata;
- WCHAR* pwMask = new WCHAR[wcslen(g_pwDllDir)+6+1];
- wcscpy(pwMask, g_pwDllDir);
- wcscat(pwMask, L"\\*.txt");
- //UINT iLenMask = wcslen(swMask);
- HANDLE hFind = FindFirstFile(pwMask, &ffdata);
- if( hFind!=INVALID_HANDLE_VALUE )
- {
- int i = 0;
- do
- {
- SUBKEYENTRY* psk = new SUBKEYENTRY;
- psk->vk = _VK_MOD;
- //psk->data.pw= new WCHAR[iLenMask-5+wcslen(ffdata.cFileName)+1];
- //wcscpy(psk->data.pw, swMask);
- //wcscpy(psk->data.pw+iLenMask-5, ffdata.cFileName);
- ffdata.cFileName[wcslen(ffdata.cFileName)-4] = '\0'; // trim .txt
- psk->data.pw= _wcsdup(ffdata.cFileName);
- psk->left = 0;
- psk->top = (i+1)*-16;
- psk->right = 80;
- psk->bottom = (i+0)*-16;
- psk->group = SK_GROUP_LATIN;
- psk->desc.pw= 0;
- m_keyCurrent->subkeys.add_first(psk);
- i ++;
- } while(FindNextFile(hFind, &ffdata));
- FindClose(hFind);
- }
- delete []pwMask;
- }
-
// кнопка Fn
if(m_keyCurrent->vk==_VK_FN)
{
@@ -1148,7 +1113,7 @@
// если нет обоев - рисуем кнопочку, если кнопка текущая - рисуем чёрную кнопочку
if(!m_hbmSkin || p==m_keyCurrent)
{
- COLORREF bgColor = p==m_keyCurrent ? RGB(0x00,0x00,0x00) : m_config->m_colors[p->group][1];
+ COLORREF bgColor = p==m_keyCurrent ? RGB(0xff,0xff,0xff) : m_config->m_colors[p->group][1];
CGdiObj>HBRUSH> hBrushBg2 = CreateSolidBrush(bgColor);
assert(hBrushBg2);
DrawButton(hdc, r0, hBrushBg2, hPenTL, hPenBR);
@@ -1158,13 +1123,13 @@
if (0!=p->data.pw)
{
SelectObject(hdc, m_hFontBig);
- COLORREF fgColor = p==m_keyCurrent ? RGB(0xFF,0xFF,0xFF) : m_config->m_colors[p->group][0];
+ COLORREF fgColor = p==m_keyCurrent ? RGB(0x00,0x00,0x00) : m_config->m_colors[p->group][0];
DrawText(hdc, p->data, &rText, DT_NOPREFIX | DT_BOTTOM | DT_LEFT, fgColor);

if (0!=p->desc.pw) // надстрочный знак
{
SelectObject(hdc, m_hFontIndex);
- COLORREF fgColor2 = p==m_keyCurrent ? RGB(0xFF,0xFF,0xFF) : m_config->m_colorDesc;
+ COLORREF fgColor2 = p==m_keyCurrent ? RGB(0x00,0x00,0x00) : m_config->m_colorDesc;
//if(0!=p->desc2.pw) // есть оба знака - надстрочный двинем чуть левее
// rText.right -= 7*m_vga;
DrawText(hdc, p->desc, &rText, DT_NOPREFIX | DT_RIGHT | DT_TOP, fgColor2);
@@ -1175,13 +1140,13 @@
{
rText.top += 4*m_vga;
SelectObject(hdc, m_hFontIndex);
- COLORREF fgColor2 = p==m_keyCurrent ? RGB(0xFF,0xFF,0xFF) : m_config->m_colorDesc2;
+ COLORREF fgColor2 = p==m_keyCurrent ? RGB(0x00,0x00,0x00) : m_config->m_colorDesc2;
DrawText(hdc, p->desc2, &rText, DT_NOPREFIX | DT_RIGHT | DT_TOP, fgColor2);
}
} else if (0!=p->desc.pw) // текст вроде 'Caps'
{
SelectObject(hdc, m_hFontSmall);
- COLORREF fgColor2 = p==m_keyCurrent ? RGB(0xFF,0xFF,0xFF) : m_config->m_colors[p->group][0];
+ COLORREF fgColor2 = p==m_keyCurrent ? RGB(0x00,0x00,0x00) : m_config->m_colors[p->group][0];
DrawText(hdc, p->desc, &rText, DT_NOPREFIX | DT_CENTER | DT_VCENTER, fgColor2);
}
}
@@ -1205,7 +1170,6 @@
{
m_keyCurrent = pKey;
if(0==m_nPopupDelay ||
- m_keyCurrent->vk==_VK_MOD ||
m_keyCurrent->vk==_VK_FN )
{
PopUp();



Долой стилус!

Комментариев нет:

Отправить комментарий