📄 haneaseengine.cpp
字号:
#include <w32std.h>
#include "haneaseengine.h"
#include "fepcontrol.h"
#include "logger.h"
const TInt KMaxNumOfKeys = 10;
const TInt KMaxCandNum = 10;
const TInt KMultiTapTimeout = 1000000; // 1.0s
struct TKeymap
{
char* iKeyString;
TInt iSize;
};
const struct TKeymap KKeymap[KMaxNumOfKeys] = {
{ " 0", 2 },
{ "1+#.,@?!\"\'/&", 12 },
{ "abc2", 4 },
{ "def3", 4 },
{ "ghi4", 4 },
{ "jkl5", 4 },
{ "mno6", 4 },
{ "pqrs7", 5 },
{ "tuv8", 4 },
{ "wxyz9", 5 }
};
struct TCodemap
{
TUint16 iCode;
TUint16 iCh;
};
const TInt KMaxNumOfCodes = 6967;//7037;//
const struct TCodemap KCodemap[KMaxNumOfCodes] =
{
#include "liucode.h"
};
//////////////////////////////////////////////////////////////////////
//
// Class CExampleFepMultiTapEngine
//
//////////////////////////////////////////////////////////////////////
CHaneaseEngine* CHaneaseEngine::NewL(CHaneaseFepControl& aControl, TDes16& aInput, CArrayFix<TUint> &aCand, CArrayFix<TUint> &aOutput)
{
CHaneaseEngine* self = new(ELeave)CHaneaseEngine(aControl, aInput, aCand, aOutput);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(); // self
return self;
}
CHaneaseEngine::CHaneaseEngine(CHaneaseFepControl& aControl, TDes16& aInput, CArrayFix<TUint> &aCand, CArrayFix<TUint> &aOutput)
: iFepControl(aControl), iInput(aInput), iCand(aCand), iOutput(aOutput)
{
}
void CHaneaseEngine::ConstructL()
{
iTimer = new (ELeave) CHaneaseTimer;
iTimer->ConstructL(this);
}
CHaneaseEngine::~CHaneaseEngine()
{
delete iTimer;
iTimer = NULL;
}
void CHaneaseEngine::AppenChar(TInt aKeyCode)
{
TInt offset = aKeyCode - '0';
iKeyPos = 0;
char ch = KKeymap[offset].iKeyString[iKeyPos];
TBuf<1> buffer = KNullDesC();
buffer.Append(ch);
iInput.Append(buffer);
}
void CHaneaseEngine::ChangeLastChar(TInt aKeyCode)
{
TInt offset = aKeyCode - '0';
iKeyPos++;
if ( iKeyPos >= KKeymap[offset].iSize-1)
iKeyPos = 0;
char ch = KKeymap[offset].iKeyString[iKeyPos];
TBuf<1> buffer = KNullDesC();
buffer.Append(ch);
iInput.SetLength(iInput.Length()-1);
iInput += buffer;
}
TKeyResponse CHaneaseEngine::DelChar()
{
TKeyResponse ret = iInput.Length()>0?EKeyWasConsumed:EKeyWasNotConsumed;
if(iInput.Length()>1)
{
iInput.SetLength(iInput.Length()-1);
MakeCand();
return ret;
}
else
{
iFepControl.Reset();
iFepControl.DisplayFep();
return ret;
}
}
void CHaneaseEngine::CommitCand()
{
iFepControl.CommitOutput();
iFepControl.DisplayFep();
}
void CHaneaseEngine::PrePage()
{
if(iCur>iStart)
{
iCur -= KMaxCandNum;
iFepControl.iHighlight = 0;
MakeCandArray();
}
}
void CHaneaseEngine::NextPage()
{
if(iCur+KMaxCandNum<=iEnd)
{
iCur += KMaxCandNum;
iFepControl.iHighlight = 0;
MakeCandArray();
}
}
void CHaneaseEngine::PreCand()
{
TInt &highlight = iFepControl.iHighlight;
if(highlight>0)
{
highlight --;
iFepControl.DisplayFep();
}
else
PrePage();
}
void CHaneaseEngine::NextCand()
{
TInt max = iEnd-iCur;
max = max>(KMaxCandNum-1)?(KMaxCandNum-1):max;
TInt &highlight = iFepControl.iHighlight;
if(highlight<max)
{
highlight ++;
iFepControl.DisplayFep();
}
else
NextPage();
}
void CHaneaseEngine::MakeCandArray()
{
iCand.Reset();
if(iCur != -1)
{
TInt i;
for(i = iCur; i<=iEnd; i++)
{
iCand.AppendL(KCodemap[i].iCh);
if(i == iCur+ KMaxCandNum -1)
break;
}
}
iFepControl.DisplayFep();
}
void CHaneaseEngine::MakeCand()
{
//LOG_METHOD(_L("CHaneaseEngine::MakeCand"));
TUint16 code, mask, curcode;
switch(iInput.Length())
{
case 1:
code = (iInput[0]-'a'+1)<<10;
mask = 0x7c00;
break;
case 2:
code = ((iInput[0]-'a'+1)<<10) + ((iInput[1]-'a'+1)<<5);
mask = 0x7fe0;
break;
case 3:
code = ((iInput[0]-'a'+1)<<10) + ((iInput[1]-'a'+1)<<5)+ (iInput[2]-'a'+1);
mask = 0x7fff;
break;
}
//WRITE_LOG_FORMAT2(_L("len = %d, code=%d"), iInput.Length(), code);
TInt start = 0, end = KMaxNumOfCodes-1, mid, savemid, saveend;
for(;;)
{
mid = (start +end)/2;
curcode = KCodemap[mid].iCode&mask;
//WRITE_LOG_FORMAT2(_L("%d=%d, "), mid, curcode);
//WRITE_LOG_FORMAT2(_L("%d-%d, "), start, end);
if(curcode>code)
end = mid;
else if(curcode<code)
{
if(start == mid)
{//no cand
if((KCodemap[end].iCode&mask) == code)
iStart = iCur = iEnd = end;
else
iStart = iCur = iEnd = -1;
MakeCandArray();
return;
}
else
start = mid;
}
else
break;
}
//WRITE_LOG_FORMAT2(_L("find mid = %d, code=0x%x"), mid, code);
savemid = mid;
saveend = end;
if((KCodemap[0].iCode&mask) == code)
iStart = 0;
else
{
end = mid;
for(;;)
{
mid = (start +end)/2;
curcode = KCodemap[mid].iCode&mask;
if(curcode<code)
{
if(start == mid)
{
//WRITE_LOG_FORMAT2(_L("finding start mid=%d end=%d"), KCodemap[mid].iCode&mask, KCodemap[end].iCode&mask);
mid = end;
break;
}
else
start = mid;
}
else if((KCodemap[mid-1].iCode&mask) == code)
end = mid;
else
break;
}
iStart = mid;
}
if((KCodemap[KMaxNumOfCodes -1].iCode&mask) == code)
iEnd = KMaxNumOfCodes -1;
else
{
start = savemid;
end = saveend;
for(;;)
{
mid = (start +end)/2;
curcode = KCodemap[mid].iCode&mask;
//WRITE_LOG_FORMAT2(_L("%d=%d, "), mid, curcode);
//WRITE_LOG_FORMAT2(_L("%d-%d, "), start, end);
if(curcode>code)
{
if(end == mid)
break;
else
end = mid;
}
else if((KCodemap[mid+1].iCode&mask) == code)
start = mid;
else
break;
}
iEnd = mid;
}
iCur = iStart;
//WRITE_LOG_FORMAT2(_L("iStart = %d iEnd=%d, "), iStart, iEnd);
MakeCandArray();
}
TKeyResponse CHaneaseEngine::OnKey(TInt aKeyCode)
{
TKeyResponse ret = EKeyWasNotConsumed;
WRITE_LOG_FORMAT(_L("CHaneaseEngine::OnKey 0x%x, "), aKeyCode);
if(aKeyCode<'2'||aKeyCode>'9')
{
if(iTimer->IsActive())
iTimer->Cancel();
iPrekey = 0;
}
if(aKeyCode>='2'&&aKeyCode<='9')
{
if(aKeyCode==iPrekey && iTimer->IsActive())
{
ChangeLastChar(aKeyCode);
MakeCand();
}
else
{
if(iInput.Length()==3)
{
CommitCand();
}
AppenChar(aKeyCode);
MakeCand();
}
iPrekey = aKeyCode;
iTimer->Restart();
ret = EKeyWasConsumed;
}
else if(aKeyCode=='c')
{
ret = DelChar();
}
else if(aKeyCode=='0')
{
if(iInput.Length()>0)
CommitCand();
iCand.AppendL(0x0020);
iFepControl.CommitOutput();
iFepControl.DisplayFep();
ret = EKeyWasConsumed;
}
else if(aKeyCode=='1')
{
if(iInput.Length()>0)
CommitCand();
iCand.AppendL(0x3002);
iFepControl.CommitOutput();
iFepControl.DisplayFep();
ret = EKeyWasConsumed;
}
else if(iInput.Length()>0)//pre, next, pageup, pagedown
{
switch(aKeyCode)
{
case '-':
PrePage();
break;
case '+':
NextPage();
break;
case '<':
PreCand();
break;
case '>':
NextCand();
break;
default:
CommitCand();
break;
}
}
return ret;
}
void CHaneaseEngine::OnTimer()
{
iPrekey = 0;
}
CMultiTapEngine::CMultiTapEngine(CHaneaseFepControl& aControl, TDes16& aInput, CArrayFix<TUint> &aCand, CArrayFix<TUint> &aOutput)
: iFepControl(aControl), iInput(aInput), iCand(aCand), iOutput(aOutput)
{
}
CMultiTapEngine::~CMultiTapEngine()
{
delete iTimer;
iTimer = NULL;
}
CMultiTapEngine* CMultiTapEngine::NewL (CHaneaseFepControl& aControl, TDes16& aInput, CArrayFix<TUint> &aCand, CArrayFix<TUint> &aOutput)
{
CMultiTapEngine* self = new(ELeave)CMultiTapEngine(aControl, aInput, aCand, aOutput);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(); // self
return self;
}
void CMultiTapEngine::ConstructL()
{
iTimer = new (ELeave) CHaneaseTimer;
iTimer->ConstructL(this);
}
void CMultiTapEngine::CommitInput()
{
iFepControl.iHighlight = 0;
iCand.AppendL(iInput[0]);
iFepControl.DisplayFep();
iFepControl.CommitOutput();
}
TKeyResponse CMultiTapEngine::OnKey(TInt aKeyCode)
{
TKeyResponse ret = EKeyWasNotConsumed;
if(aKeyCode<'0'||aKeyCode>'9')
{
if(iTimer->IsActive())
iTimer->Cancel();
iPrekey = 0;
if(aKeyCode == 'c' && iInput.Length()>0)
{
iInput.Zero();
ret = EKeyWasConsumed;
}
else if(iInput.Length()>0)
CommitInput();
iFepControl.DisplayFep();
return ret;
}
if(iPrekey!=aKeyCode && iInput.Length()>0)
CommitInput();
TInt offset = aKeyCode - '0';
if(iTimer->IsActive()&&iPrekey==aKeyCode)
{
iKeyPos++;
if ( iKeyPos >= KKeymap[offset].iSize)
iKeyPos = 0;
}
else
{
iKeyPos = 0;
}
char ch = KKeymap[offset].iKeyString[iKeyPos];
iInput = KNullDesC();
iInput.Append(ch);
iPrekey = aKeyCode;
iTimer->Restart();
iFepControl.DisplayFep();
return EKeyWasConsumed;
}
void CMultiTapEngine::OnTimer()
{
CommitInput();
iFepControl.DisplayFep();
}
CHaneaseTimer::CHaneaseTimer(): CTimer(EPriorityNormal)
{}
void CHaneaseTimer::ConstructL(MTimerNotifier *aEngine)
{
CTimer::ConstructL();
CActiveScheduler::Add(this);
iEngine = aEngine;
}
void CHaneaseTimer::Restart()
{
if(IsActive())
Cancel();
After(KMultiTapTimeout);
}
void CHaneaseTimer::RunL()
{
iEngine->OnTimer();
}
/*
#include <stdio.h>
typedef char* __e32_va_list;
#define va_list __e32_va_list
#define va_start(ap,pn) (ap=(__e32_va_list)&pn+((sizeof(pn)+sizeof(int)-1)&~(sizeof(int)-1)),(void)0)
#define va_arg(ap,type) (ap+=((sizeof(type)+sizeof(int)-1)&~(sizeof(int)-1)),(*(type *)(ap-((sizeof(type)+sizeof(int)-1)&~(sizeof(int)-1)))))
#define va_end(ap) (ap=0,(void)0)
__declspec(dllimport)
void
__stdcall
OutputDebugStringA(
char* lpOutputString
);
__declspec(dllimport)
void
__stdcall
OutputDebugStringW(
char* lpOutputString
);
int dprintf(const char *fmt, ...)
{
int ret;
char msg[1024];
va_list args;
va_start(args, fmt);
ret = vsprintf(msg, fmt, args);
va_end(args);
if (strlen(msg)>=800) {
OutputDebugStringA("[DPRINTF] Buffer OverFlow\n");
// DebugBreak();
}
OutputDebugStringA(msg);
return ret;
}*/
// end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -