⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 haneaseengine.cpp

📁 三字经输入法源码
💻 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 + -