中文输入法--WP8
windows app 程序要实现能够屏幕分屏。而且要做到自适应。
问题一:需要将utf8格式的 std:string 转为 std:wstring
代码如下:
std::wstring FromUtf8(const std::string& utf8string)
{
size_t widesize = utf8string.length();
if (sizeof(wchar_t) == 2)
{
std::wstring resultstring;
resultstring.resize(widesize+1, L'\0');
const UTF8* sourcestart = reinterpret_cast<const UTF8*>(utf8string.c_str());
const UTF8* sourceend = sourcestart + widesize;
UTF16* targetstart = reinterpret_cast<UTF16*>(&resultstring[0]);
UTF16* targetend = targetstart + widesize;
ConversionResult res = ConvertUTF8toUTF16
(&sourcestart, sourceend, &targetstart, targetend, strictConversion);
if (res != conversionOK)
{
throw std::exception("La falla!");
}
*targetstart = 0;
return resultstring;
}
else if (sizeof(wchar_t) == 4)
{
std::wstring resultstring;
resultstring.resize(widesize+1, L'\0');
const UTF8* sourcestart = reinterpret_cast<const UTF8*>(utf8string.c_str());
const UTF8* sourceend = sourcestart + widesize;
UTF32* targetstart = reinterpret_cast<UTF32*>(&resultstring[0]);
UTF32* targetend = targetstart + widesize;
ConversionResult res = ConvertUTF8toUTF32
(&sourcestart, sourceend, &targetstart, targetend, strictConversion);
if (res != conversionOK)
{
throw std::exception("La falla!");
}
*targetstart = 0;
return resultstring;
}
else
{
throw std::exception("La falla!");
}
return L"";
}
修改后的SkWord代码如下:
void SkWord::setStr(string str, SkFont & font, Uint8 r, Uint8 g, Uint8 b,
Uint8 a) {
m_skSurface.m_bWord = true;
#ifdef __WP8__
m_skSurface.r = r;
m_skSurface.g = g;
m_skSurface.b = b;
m_skSurface.a = a;
m_str = str;
//std::wstring st = stows(m_str.c_str());
std::wstring st = FromUtf8(m_str);
Platform::String ^ mystr = ref new Platform::String(st.c_str());
g_SkComm.getRenderer()->m_dwriteFactory->CreateTextLayout(mystr->Data(),mystr->Length(),
font.m_textFormat.Get(),
2000,// maxWidth
_B2S(font.getSize()),// maxHeight
&m_skSurface.m_textStr);
DWRITE_TEXT_METRICS metrics;
m_skSurface.m_textStr->GetMetrics(&metrics);
m_skSurface.m_wO =metrics.width;
m_skSurface.m_hO = metrics.height;
m_skSurface.m_h = font.getSize();
m_skSurface.m_w = m_skSurface.m_wO * m_skSurface.m_h / m_skSurface.m_hO;
m_skSurface.m_wS = _B2S(m_skSurface.m_w);
m_skSurface.m_hS = _B2S(m_skSurface.m_h);
#else
m_str = str;
if (m_str.length() > 0) {
SDL_Color c;
c.r = r;
c.g = g;
c.b = b;
c.a = a;
SDL_Surface *message = TTF_RenderUTF8_Solid(font.getPtr(), str.c_str(),
c);
//SDL_Surface *message = TTF_RenderText_Solid(font.getPtr(), str.c_str(), c);
SDL_Texture * pSDL_Texture = SDL_CreateTextureFromSurface(
g_SkShow.m_pSkRenderer, message);
m_skSurface.setSurface(pSDL_Texture);
m_skSurface.m_wO = message->w;
m_skSurface.m_hO = message->h;
m_skSurface.m_h = font.getSize();
m_skSurface.m_w = m_skSurface.m_wO * m_skSurface.m_h / m_skSurface.m_hO;
m_skSurface.m_wS = _B2S(m_skSurface.m_w);
m_skSurface.m_hS = _B2S(m_skSurface.m_h);
} else {
m_skSurface.setSurface(NULL);
m_skSurface.m_wO = 0;
m_skSurface.m_hO = 0;
m_skSurface.m_h = 0;
m_skSurface.m_w = 0;
m_skSurface.m_wS = 0;
m_skSurface.m_hS = 0;
}
#endif
}
问题二:字体自适应的问题。
解决方法有两种:字体拉伸(SDL框架使用了这种方案)(这个方法因为我找到的方法没有起作用而暂时放弃。以后有机会再尝试)
第二种方法:计算好字体的大小,加载合适大小的字体。
代码如下:
#ifndef SKWORD_H_
#define SKWORD_H_
#include "SkComm.h"
#include <string>
using namespace std;
namespace sk_park {
class SkFont {
public:
SkFont();
void init(const char * pPath, Sint32 iSize);
~SkFont();
#ifdef __WP8__
#else
TTF_Font * getPtr();
#endif
Sint32 getSize();
private:
Sint32 m_iSize;
#ifdef __WP8__
public:
FontFamily^ m_refFontFamily;
Microsoft::WRL::ComPtr<IDWriteTextFormat> m_textFormat;
#else
TTF_Font * m_pFont;
#endif
};
class SkWord {
public:
string m_str;
SkSurface m_skSurface;
void setStr(string str, SkFont & font, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
};
}
extern sk_park::SkWord g_SkWord;
extern sk_park::SkFont g_SkFont;
#endif /* SKWORD_H_ */
#include "pch.h"
#include "SkWord.h"
#include "SkFile.h"
#include "SkShow.h"
using namespace sk_park;
SkFont::SkFont() {
#ifndef __WP8__
m_pFont = NULL;
#endif
m_iSize = 0;
}
void SkFont::init(const char * pPath, Sint32 iSize) {
m_iSize = iSize;
#ifdef __WP8__
float fSize = (int)(_B2S(m_iSize)*72.0/96.0);
// Platform::String ^ str = ref new Platform::String(stows("font/roboto.ttf#Roboto").c_str());
// m_refFontFamily = ref new FontFamily(str);
g_SkComm.getRenderer()->m_dwriteFactory->CreateTextFormat(L"黑体", nullptr,
DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL, fSize, L"en-US",
&m_textFormat);
#else
float fSize = _B2S(m_iSize);
SkString sPath = pPath;
#ifdef __ANDROID__
sPath.replaceAll('/','-');
#endif
char fontPath[256];
snprintf(fontPath, sizeof(fontPath), "%s/%s", g_SkFile.getRootPath(),
sPath.c_str());
m_pFont = TTF_OpenFont(fontPath,fSize);
g_SkComm.log("[%s][%d]g_font:%d path=%s", __FILE__, __LINE__, m_pFont,
fontPath);
#ifdef __ANDROID__
if (m_pFont == NULL) {
SkString sData;
int iRet = g_SkFile.readAndroidFile(pPath,sData);
g_SkComm.log("[%s][%d]readAndroidFile=%d path=%s", __FILE__, __LINE__,iRet,pPath);
if(iRet==0) {
iRet = g_SkFile.saveBinFile(sPath.c_str(),sData);
g_SkComm.log("[%s][%d]saveBinFile=%d path=%s", __FILE__, __LINE__,iRet,sPath.c_str());
}
}
m_pFont = TTF_OpenFont(fontPath,fSize);
g_SkComm.log("[%s][%d]g_font2:%d path=%s", __FILE__, __LINE__, m_pFont,
fontPath);
#endif
if (m_pFont == NULL) {
g_SkComm.myexit();
}
#endif
}
SkFont::~SkFont() {
#ifndef __WP8__
if (m_pFont != NULL) {
TTF_CloseFont(m_pFont);
m_pFont = NULL;
}
#endif
}
#ifndef __WP8__
TTF_Font * SkFont::getPtr() {
return m_pFont;
}
#endif
Sint32 SkFont::getSize() {
return m_iSize;
}
void SkWord::setStr(string str, SkFont & font, Uint8 r, Uint8 g, Uint8 b,
Uint8 a) {
m_skSurface.m_bWord = true;
#ifdef __WP8__
m_skSurface.r = r;
m_skSurface.g = g;
m_skSurface.b = b;
m_skSurface.a = a;
m_str = str;
//std::wstring st = stows(m_str.c_str());
std::wstring st = FromUtf8(m_str);
Platform::String ^ mystr = ref new Platform::String(st.c_str());
g_SkComm.getRenderer()->m_dwriteFactory->CreateTextLayout(mystr->Data(),mystr->Length(),
font.m_textFormat.Get(),
2000,// maxWidth
_B2S(font.getSize()),// maxHeight
&m_skSurface.m_textStr);
DWRITE_TEXT_METRICS metrics;
m_skSurface.m_textStr->GetMetrics(&metrics);
m_skSurface.m_wO =metrics.width;
m_skSurface.m_hO = metrics.height;
m_skSurface.m_h = font.getSize();
m_skSurface.m_w = m_skSurface.m_wO * m_skSurface.m_h / m_skSurface.m_hO;
m_skSurface.m_wS = _B2S(m_skSurface.m_w);
m_skSurface.m_hS = _B2S(m_skSurface.m_h);
#else
m_str = str;
if (m_str.length() > 0) {
SDL_Color c;
c.r = r;
c.g = g;
c.b = b;
c.a = a;
SDL_Surface *message = TTF_RenderUTF8_Solid(font.getPtr(), str.c_str(),
c);
//SDL_Surface *message = TTF_RenderText_Solid(font.getPtr(), str.c_str(), c);
SDL_Texture * pSDL_Texture = SDL_CreateTextureFromSurface(
g_SkShow.m_pSkRenderer, message);
m_skSurface.setSurface(pSDL_Texture);
m_skSurface.m_wO = message->w;
m_skSurface.m_hO = message->h;
m_skSurface.m_h = font.getSize();
m_skSurface.m_w = m_skSurface.m_wO * m_skSurface.m_h / m_skSurface.m_hO;
m_skSurface.m_wS = _B2S(m_skSurface.m_w);
m_skSurface.m_hS = _B2S(m_skSurface.m_h);
} else {
m_skSurface.setSurface(NULL);
m_skSurface.m_wO = 0;
m_skSurface.m_hO = 0;
m_skSurface.m_h = 0;
m_skSurface.m_w = 0;
m_skSurface.m_wS = 0;
m_skSurface.m_hS = 0;
}
#endif
}
SkWord g_SkWord;
SkFont g_SkFont;
绘制字体的函数如下:
#include "pch.h"
#include "SkShow.h"
using namespace sk_park;
void SkShow::init(SkRenderer * pSkRenderer) {
m_pSkRenderer = pSkRenderer;
}
void SkShow::flush() {
#ifdef __WP8__
#else
SDL_RenderPresent(m_pSkRenderer);
#endif
}
void SkShow::clear(Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
#ifdef __WP8__
m_pSkRenderer->m_d2dContext.Get()->Clear(D2D1::ColorF::ColorF(r,g,b,a));
#else
SDL_SetRenderDrawColor(m_pSkRenderer, r, g, b, a);
SDL_RenderClear(m_pSkRenderer);
#endif
}
void SkShow::drawRec(SkRect * pArea, Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
SkRect sTRec;
#ifdef HAVE_OPENGL
sTRec.x = _B2SX(pArea->x)+g_gl_left;
sTRec.y = _B2SY(pArea->y)+g_gl_top;
//sTRec.x = _B2SX(pArea->x);
//sTRec.y = _B2SY(pArea->y);
#else
sTRec.x = _B2SX(pArea->x);
sTRec.y = _B2SY(pArea->y);
#endif
sTRec.w = _B2S(pArea->w);
sTRec.h = _B2S(pArea->h);
#ifdef __WP8__
m_pSkRenderer->m_colorBrush.Get()->SetColor(D2D1::ColorF::ColorF(r,g,b,a));
m_pSkRenderer->m_d2dContext.Get()->DrawRectangle(
D2D1::RectF(sTRec.x, sTRec.y, sTRec.x+sTRec.w,sTRec.y+sTRec.h), m_pSkRenderer->m_colorBrush.Get());
#else
SDL_SetRenderDrawColor(m_pSkRenderer, r, g, b, a);
SDL_RenderDrawRect(m_pSkRenderer, &sTRec);
#endif
}
void SkShow::fillRec(SkRect * pArea, Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
SkRect sTRec;
#ifdef HAVE_OPENGL
sTRec.x = _B2SX(pArea->x)+g_gl_left;
sTRec.y = _B2SY(pArea->y)+g_gl_top;
//sTRec.x = _B2SX(pArea->x);
//sTRec.y = _B2SY(pArea->y);
#else
sTRec.x = _B2SX(pArea->x);
sTRec.y = _B2SY(pArea->y);
#endif
sTRec.w = _B2S(pArea->w);
sTRec.h = _B2S(pArea->h);
#ifdef __WP8__
m_pSkRenderer->m_colorBrush.Get()->SetColor(D2D1::ColorF::ColorF(r,g,b,a));
m_pSkRenderer->m_d2dContext.Get()->FillRectangle(
D2D1::RectF(sTRec.x, sTRec.y, sTRec.x+sTRec.w,sTRec.y+sTRec.h), m_pSkRenderer->m_colorBrush.Get());
#else
SDL_SetRenderDrawColor(m_pSkRenderer, r, g, b, a);
SDL_RenderFillRect(m_pSkRenderer, &sTRec);
#endif
}
void SkShow::drawWord(SkRect * pDesArea, SkWord* pWd, SkRect * pPicArea,
Sint64 iTime) {
drawPic(pDesArea, &pWd->m_skSurface, pPicArea);
}
void SkShow::drawButton(SkRect * pDesArea, SkButton* pBt, SkRect * pPicArea,
Sint64 iTime) {
SkSurface * pFace = pBt->getShow(iTime);
if (pPicArea == NULL) {
SkRect stRect;
stRect.x = pBt->m_iPosX;
stRect.y = pBt->m_iPosY;
drawPic(pDesArea, pFace, &stRect);
} else {
drawPic(pDesArea, pFace, pPicArea);
}
}
void SkShow::drawAnm(SkRect * pDesArea, SkAnimation* pAnm, SkRect * pPicArea,
Sint64 iTime) {
SkSurface * pFace = pAnm->getShow(iTime);
drawPic(pDesArea, pFace, pPicArea);
}
void SkShow::drawPic(SkRect * pDesArea, SkImage* pPic, SkRect * pPicArea) {
drawPic(pDesArea, &pPic->m_skSurface, pPicArea);
}
void SkShow::drawPic(SkRect * pDesArea, SkSurface* pFace, SkRect * pPicArea) {
SkRect sTRec;
#ifdef HAVE_OPENGL
#ifdef __SKYPARK_IPHONE__
sTRec.x = _B2SX(pPicArea->x);
sTRec.y = _B2SY(pPicArea->y);
#else
sTRec.x = _B2SX(pPicArea->x)+g_gl_left;
sTRec.y = _B2SY(pPicArea->y)+g_gl_top;
#endif
#else
sTRec.x = _B2SX(pPicArea->x);
sTRec.y = _B2SY(pPicArea->y);
#endif
sTRec.w = pFace->m_wS;
sTRec.h = pFace->m_hS;
#ifdef __WP8__
D2D1_POINT_2F stPos;
stPos.x = sTRec.x;
stPos.y = sTRec.y;
if (pFace->m_textStr.Get()) {
m_pSkRenderer->m_colorBrush.Get()->SetColor(D2D1::ColorF::ColorF(pFace->r,pFace->g,pFace->b,pFace->a));
m_pSkRenderer->m_d2dContext.Get()->DrawTextLayout(stPos, pFace->m_textStr.Get(),
//m_pSkRenderer->m_colorBrush.Get(), D2D1_DRAW_TEXT_OPTIONS_NO_SNAP);
m_pSkRenderer->m_colorBrush.Get(), D2D1_DRAW_TEXT_OPTIONS_CLIP);
} else {
m_pSkRenderer->m_d2dContext.Get()->DrawImage(pFace->m_pSurface.Get(), stPos);
}
#else
SDL_RenderCopy(m_pSkRenderer, pFace->getSurface(), pDesArea, &sTRec);
#endif
}
SkShow g_SkShow;
最终输入框的代码如下:
#ifndef SKVIEWINPUT_H_
#define SKVIEWINPUT_H_
#include "SkView.h"
#include "SkButton.h"
#include "SkWord.h"
#include "SkString.h"
#include <vector>
using namespace std;
/**键盘按钮点击事件**/
void sk_button_keyboard_pressed(void * pData, sk_park::SkButton * pButton);
namespace sk_park {
/**键盘输入展示界面**/
class SkViewInput: public SkView {
public:
/**定义键盘布局**/
class Keyboard {
public:
SkButton m_bt_zm[200];
Sint32 m_iSize;
Sint32 m_iShift;
void resize();
void init(SkFont * pFont, void (*func_pressed)(void *, SkButton *),
int iX, int iY);
void show(SkShow* pSkShow, Sint64 iCurMTime);
bool doEvent(SkEvent & stSkEvent, Sint64 iCurMTime, SkView * pView);
private:
SkFont * m_pFont;
Sint32 m_iPosX;
Sint32 m_iPosY;
};
~SkViewInput();
void init();
void doEvent(SkEvent & stSkEvent, Sint64 iCurMTime);
void show(SkShow* pSkShow, Sint64 iCurMTime);
void run(Sint64 iCurMTime);
void resize();
/**设置shift按键切换**/
void setShift();
/**设置中英文输入法切换**/
void setEnglish(bool bFlag);
/**添加一个输入**/
void addInput(int iId, string sIn);
/**删除一个输入**/
void delInput();
/**向前搜索**/
void doSearchPrevious();
/**向后搜索**/
void doSearchNext();
private:
void refresh();
/**查找拼音匹配**/
void doSearch(const char * pingyin, int iPos);
/**记录当前是否为英文输入法**/
bool m_bEnglish;
/**输入框内字符窜展示的最大宽度**/
Sint32 m_strMaxLen;
/**当前输入框内容**/
SkWord m_curWord;
/**输入历史**/
vector<string> m_vctStr;
/**返回按键**/
SkButton m_backButton;
/**英文字体**/
SkFont m_font_en;
/**中文字体**/
SkFont m_font_ch;
/**模拟键盘**/
Keyboard m_keyboard;
/**英文输入按键**/
SkButton m_bt_english;
/**中文输入按键**/
SkButton m_bt_chinese;
/**中文拼音临时存放**/
SkString m_pingyin;
SkWord m_pingyin_word;
SkString m_search;
vector<SkButton *> m_vctSearchButton;
/**键盘位置**/
Sint32 m_iKeyboardX;
Sint32 m_iKeyboardY;
/**记录当前搜索点**/
Sint32 m_iSearchBegin;
/**每次搜索展示字符个数**/
Sint32 m_iEachNumber;
/**WP计算空格长度**/
SkWord m_dotWord;
Sint32 m_iDotNum;
};
}
extern sk_park::SkViewInput g_SkViewInput;
#endif /* SKVIEWINPUT_H_ */
#include "pch.h"
#include "SkViewInput.h"
#include "SkZiku.h"
#include "../sk_src/SkFunction.h"
using namespace sk_park;
void SkViewInput::Keyboard::resize() {
//SkButton m_bt_zm[39];
int iSize = m_iSize - 10;
for (int i = 0; i < 50; i++) {
SkWord wordIn, wordOut, wordPressed;
wordIn.setStr(m_bt_zm[i].m_sName.c_str(), *m_pFont, 255, 0, 0, 255);
wordOut.setStr(m_bt_zm[i].m_sName.c_str(), *m_pFont, 0, 255, 0, 255);
wordPressed.setStr(m_bt_zm[i].m_sName.c_str(), *m_pFont, 255, 255, 0,
255);
m_bt_zm[i].setShow(wordIn.m_skSurface, wordOut.m_skSurface,
wordPressed.m_skSurface);
m_bt_zm[i].m_area.clear();
m_bt_zm[i].m_area.addPoint(0, 0);
m_bt_zm[i].m_area.addPoint(iSize, 0);
m_bt_zm[i].m_area.addPoint(iSize, iSize);
m_bt_zm[i].m_area.addPoint(0, iSize);
}
for (int i = 100; i < 150; i++) {
SkWord wordIn, wordOut, wordPressed;
wordIn.setStr(m_bt_zm[i].m_sName.c_str(), *m_pFont, 255, 0, 0, 255);
wordOut.setStr(m_bt_zm[i].m_sName.c_str(), *m_pFont, 0, 255, 0, 255);
wordPressed.setStr(m_bt_zm[i].m_sName.c_str(), *m_pFont, 255, 255, 0,
255);
m_bt_zm[i].setShow(wordIn.m_skSurface, wordOut.m_skSurface,
wordPressed.m_skSurface);
m_bt_zm[i].m_area.clear();
m_bt_zm[i].m_area.addPoint(0, 0);
m_bt_zm[i].m_area.addPoint(iSize, 0);
m_bt_zm[i].m_area.addPoint(iSize, iSize);
m_bt_zm[i].m_area.addPoint(0, iSize);
}
}
void SkViewInput::Keyboard::init(SkFont * pFont,
void (*func_pressed)(void *, SkButton *), int iX, int iY) {
m_iPosX = iX;
m_iPosY = iY;
m_iShift = 0;
m_iSize = 90;
m_pFont = pFont;
int iSize = m_iSize;
int iPosX = m_iPosX;
int iPosY = m_iPosY;
int iLine1 = 12;
int iLine2 = 13;
int iLine3 = 13;
int iLine4 = 12;
int iTLen = 25;
for (int i = 0; i < iLine1; i++) {
m_bt_zm[i].m_iPosX = iPosX + iSize * i;
m_bt_zm[i].m_iPosY = iPosY;
m_bt_zm[i + 100].m_iPosX = iPosX + iSize * i;
m_bt_zm[i + 100].m_iPosY = iPosY;
}
for (int i = 0; i < iLine2; i++) {
m_bt_zm[i + iLine1].m_iPosX = iPosX + iSize * i + iSize / 2;
m_bt_zm[i + iLine1].m_iPosY = iPosY + iSize + iTLen * 1;
m_bt_zm[i + 100 + iLine1].m_iPosX = iPosX + iSize * i + iSize / 2;
m_bt_zm[i + 100 + iLine1].m_iPosY = iPosY + iSize + iTLen * 1;
}
for (int i = 0; i < iLine3; i++) {
m_bt_zm[i + iLine1 + iLine2].m_iPosX = iPosX + iSize * i + iSize;
m_bt_zm[i + iLine1 + iLine2].m_iPosY = iPosY + iSize * 2 + iTLen * 2;
m_bt_zm[i + 100 + iLine1 + iLine2].m_iPosX = iPosX + iSize * i + iSize;
m_bt_zm[i + 100 + iLine1 + iLine2].m_iPosY = iPosY + iSize * 2
+ iTLen * 2;
}
for (int i = 0; i < iLine4; i++) {
m_bt_zm[i + iLine1 + iLine2 + iLine3].m_iPosX = iPosX + iSize * i
+ iSize / 2;
m_bt_zm[i + iLine1 + iLine2 + iLine3].m_iPosY = iPosY + iSize * 3
+ iTLen * 3;
m_bt_zm[i + 100 + iLine1 + iLine2 + iLine3].m_iPosX = iPosX + iSize * i
+ iSize / 2;
m_bt_zm[i + 100 + iLine1 + iLine2 + iLine3].m_iPosY = iPosY + iSize * 3
+ iTLen * 3;
}
for (int i = 0; i < 50; i++) {
m_bt_zm[i].setFuncPressed(func_pressed);
m_bt_zm[i + 100].setFuncPressed(func_pressed);
}
for (int i = 0; i < 150; i++) {
m_bt_zm[i].m_iId = i;
m_bt_zm[i].m_bWord = true;
}
//第一行 12
m_bt_zm[0].m_sName = "1";
m_bt_zm[1].m_sName = "2";
m_bt_zm[2].m_sName = "3";
m_bt_zm[3].m_sName = "4";
m_bt_zm[4].m_sName = "5";
m_bt_zm[5].m_sName = "6";
m_bt_zm[6].m_sName = "7";
m_bt_zm[7].m_sName = "8";
m_bt_zm[8].m_sName = "9";
m_bt_zm[9].m_sName = "0";
m_bt_zm[10].m_sName = "-";
m_bt_zm[11].m_sName = "=";
//第二行 13
m_bt_zm[12].m_sName = "q";
m_bt_zm[13].m_sName = "w";
m_bt_zm[14].m_sName = "e";
m_bt_zm[15].m_sName = "r";
m_bt_zm[16].m_sName = "t";
m_bt_zm[17].m_sName = "y";
m_bt_zm[18].m_sName = "u";
m_bt_zm[19].m_sName = "i";
m_bt_zm[20].m_sName = "o";
m_bt_zm[21].m_sName = "p";
m_bt_zm[22].m_sName = "[";
m_bt_zm[23].m_sName = "]";
m_bt_zm[24].m_sName = "\\";
//第三行 13
m_bt_zm[25].m_sName = "a";
m_bt_zm[26].m_sName = "s";
m_bt_zm[27].m_sName = "d";
m_bt_zm[28].m_sName = "f";
m_bt_zm[29].m_sName = "g";
m_bt_zm[30].m_sName = "h";
m_bt_zm[31].m_sName = "j";
m_bt_zm[32].m_sName = "k";
m_bt_zm[33].m_sName = "l";
m_bt_zm[34].m_sName = ";";
m_bt_zm[35].m_sName = "'";
m_bt_zm[36].m_sName = "De";
m_bt_zm[37].m_sName = "En";
//第四行 12
m_bt_zm[38].m_sName = " ";
m_bt_zm[39].m_sName = "z";
m_bt_zm[40].m_sName = "x";
m_bt_zm[41].m_sName = "c";
m_bt_zm[42].m_sName = "v";
m_bt_zm[43].m_sName = "b";
m_bt_zm[44].m_sName = "n";
m_bt_zm[45].m_sName = "m";
m_bt_zm[46].m_sName = ",";
m_bt_zm[47].m_sName = ".";
m_bt_zm[48].m_sName = "/";
m_bt_zm[49].m_sName = "Sh";
//第一行 12
m_bt_zm[100].m_sName = "!";
m_bt_zm[101].m_sName = "@";
m_bt_zm[102].m_sName = "#";
m_bt_zm[103].m_sName = "$";
m_bt_zm[104].m_sName = "%";
m_bt_zm[105].m_sName = "^";
m_bt_zm[106].m_sName = "&";
m_bt_zm[107].m_sName = "*";
m_bt_zm[108].m_sName = "(";
m_bt_zm[109].m_sName = ")";
m_bt_zm[110].m_sName = "_";
m_bt_zm[111].m_sName = "+";
//第二行 13
m_bt_zm[112].m_sName = "Q";
m_bt_zm[113].m_sName = "W";
m_bt_zm[114].m_sName = "E";
m_bt_zm[115].m_sName = "R";
m_bt_zm[116].m_sName = "T";
m_bt_zm[117].m_sName = "Y";
m_bt_zm[118].m_sName = "U";
m_bt_zm[119].m_sName = "I";
m_bt_zm[120].m_sName = "O";
m_bt_zm[121].m_sName = "P";
m_bt_zm[122].m_sName = "{";
m_bt_zm[123].m_sName = "}";
m_bt_zm[124].m_sName = "|";
//第三行 13
m_bt_zm[125].m_sName = "A";
m_bt_zm[126].m_sName = "S";
m_bt_zm[127].m_sName = "D";
m_bt_zm[128].m_sName = "F";
m_bt_zm[129].m_sName = "G";
m_bt_zm[130].m_sName = "H";
m_bt_zm[131].m_sName = "J";
m_bt_zm[132].m_sName = "K";
m_bt_zm[133].m_sName = "L";
m_bt_zm[134].m_sName = ":";
m_bt_zm[135].m_sName = "\"";
m_bt_zm[136].m_sName = "De";
m_bt_zm[137].m_sName = "En";
//第四行 12
m_bt_zm[138].m_sName = " ";
m_bt_zm[139].m_sName = "Z";
m_bt_zm[140].m_sName = "X";
m_bt_zm[141].m_sName = "C";
m_bt_zm[142].m_sName = "V";
m_bt_zm[143].m_sName = "B";
m_bt_zm[144].m_sName = "N";
m_bt_zm[145].m_sName = "M";
m_bt_zm[146].m_sName = "<";
m_bt_zm[147].m_sName = ">";
m_bt_zm[148].m_sName = "?";
m_bt_zm[149].m_sName = "Sh";
}
void SkViewInput::Keyboard::show(SkShow* pSkShow, Sint64 iCurMTime) {
SkRect stPos;
for (int i = 0; i < 50; i++) {
stPos.x = m_bt_zm[i + m_iShift].m_iPosX
+ (m_iSize - 10 - m_bt_zm[i + m_iShift].getWidth()) / 2;
stPos.y = m_bt_zm[i + m_iShift].m_iPosY
+ (m_iSize - 10 - m_bt_zm[i + m_iShift].getHeight()) / 2;
pSkShow->drawButton(NULL, &m_bt_zm[i + m_iShift], &stPos, iCurMTime);
stPos.x = m_bt_zm[i + m_iShift].m_iPosX;
stPos.y = m_bt_zm[i + m_iShift].m_iPosY;
stPos.w = m_iSize - 10;
stPos.h = m_iSize - 10;
pSkShow->drawRec(&stPos, 255, 0, 0, 255);
}
}
bool SkViewInput::Keyboard::doEvent(SkEvent & stSkEvent, Sint64 iCurMTime,
SkView * pView) {
bool bRet = false;
for (int i = 0; i < 50; i++) {
bRet = m_bt_zm[i + m_iShift].handleEvent(m_bt_zm[i + m_iShift].m_iPosX,
m_bt_zm[i + m_iShift].m_iPosY, stSkEvent, pView);
if (bRet) {
return true;
}
}
return false;
}
SkViewInput::~SkViewInput() {
g_SkZiku.clear();
for (int i = 0; i < (int) m_vctSearchButton.size(); i++) {
SkButton * pBt = m_vctSearchButton.at(i);
delete pBt;
}
m_vctSearchButton.clear();
}
void SkViewInput::init() {
m_strMaxLen = 900;
m_bEnglish = true;
m_pingyin = "";
m_iKeyboardX = 50;
m_iKeyboardY = 50;
m_iSearchBegin = 0;
m_iEachNumber = 12;
m_iDotNum = 0;
m_font_en.init("font/simhei.ttf", 80);
m_font_ch.init("font/simhei.ttf", 60);
m_keyboard.init(&m_font_en, sk_button_keyboard_pressed, m_iKeyboardX,
m_iKeyboardY + 180);
m_curWord.setStr("", m_font_ch, 0x00, 0x00, 0x00, 0xff);
m_pingyin_word.setStr("", m_font_ch, 0xff, 0x00, 0x00, 0xff);
g_SkZiku.loadFile();
m_dotWord.setStr(".", m_font_ch, 0x00, 0x00, 0x00, 0xff);
m_bt_english.m_sName = "Eng";
m_bt_english.m_iId = 1001;
m_bt_chinese.m_sName = "中文";
m_bt_chinese.m_iId = 1002;
m_bt_english.m_bWord = true;
m_bt_chinese.m_bWord = true;
{
SkWord wordIn, wordOut, wordPressed;
wordIn.setStr(m_bt_english.m_sName.c_str(), m_font_ch, 255, 0, 0, 255);
wordOut.setStr(m_bt_english.m_sName.c_str(), m_font_ch, 0, 255, 0, 255);
wordPressed.setStr(m_bt_english.m_sName.c_str(), m_font_ch, 255, 255, 0,
255);
m_bt_english.setShow(wordIn.m_skSurface, wordOut.m_skSurface,
wordPressed.m_skSurface);
m_bt_english.m_area.clear();
m_bt_english.m_area.addPoint(0, 0);
m_bt_english.m_area.addPoint(wordIn.m_skSurface.m_w, 0);
m_bt_english.m_area.addPoint(wordIn.m_skSurface.m_w,
wordIn.m_skSurface.m_h);
m_bt_english.m_area.addPoint(0, wordIn.m_skSurface.m_h);
}
{
SkWord wordIn, wordOut, wordPressed;
wordIn.setStr(m_bt_chinese.m_sName.c_str(), m_font_ch, 255, 0, 0, 255);
wordOut.setStr(m_bt_chinese.m_sName.c_str(), m_font_ch, 0, 255, 0, 255);
wordPressed.setStr(m_bt_chinese.m_sName.c_str(), m_font_ch, 255, 255, 0,
255);
m_bt_chinese.setShow(wordIn.m_skSurface, wordOut.m_skSurface,
wordPressed.m_skSurface);
m_bt_chinese.m_area.clear();
m_bt_chinese.m_area.addPoint(0, 0);
m_bt_chinese.m_area.addPoint(wordIn.m_skSurface.m_w, 0);
m_bt_chinese.m_area.addPoint(wordIn.m_skSurface.m_w,
wordIn.m_skSurface.m_h);
m_bt_chinese.m_area.addPoint(0, wordIn.m_skSurface.m_h);
}
m_bt_english.setPosition(1000 + m_iKeyboardX, m_iKeyboardY + 20);
m_bt_chinese.setPosition(1100 + m_iKeyboardX, m_iKeyboardY + 20);
m_bt_english.setFuncPressed(sk_button_keyboard_pressed);
m_bt_chinese.setFuncPressed(sk_button_keyboard_pressed);
{
SkWord wordIn, wordOut, wordPressed;
wordIn.setStr("返回", m_font_ch, 255, 0, 0, 255);
wordOut.setStr("返回", m_font_ch, 0, 255, 0, 255);
wordPressed.setStr("返回", m_font_ch, 255, 255, 0, 255);
m_backButton.setShow(wordIn.m_skSurface, wordOut.m_skSurface,
wordPressed.m_skSurface);
m_backButton.m_area.clear();
m_backButton.m_area.addPoint(0, 0);
m_backButton.m_area.addPoint(wordIn.m_skSurface.m_w, 0);
m_backButton.m_area.addPoint(wordIn.m_skSurface.m_w,
wordIn.m_skSurface.m_h);
m_backButton.m_area.addPoint(0, wordIn.m_skSurface.m_h);
m_backButton.setPosition(1210, 670);
m_backButton.setFuncPressed(button_back_to_first);
}
resize();
}
void SkViewInput::doEvent(SkEvent & stSkEvent, Sint64 iCurMTime) {
bool bRet = m_backButton.handleEvent(m_backButton.m_iPosX,
m_backButton.m_iPosY, stSkEvent, NULL);
if (bRet) {
return;
}
bRet = m_keyboard.doEvent(stSkEvent, iCurMTime, this);
if (bRet) {
return;
}
bRet = m_bt_english.handleEvent(m_bt_english.m_iPosX, m_bt_english.m_iPosY,
stSkEvent, this);
if (bRet) {
return;
}
bRet = m_bt_chinese.handleEvent(m_bt_chinese.m_iPosX, m_bt_chinese.m_iPosY,
stSkEvent, this);
if (bRet) {
return;
}
for (int i = 0; i < (int) m_vctSearchButton.size(); i++) {
SkButton & bt = *(m_vctSearchButton.at(i));
bRet = bt.handleEvent(bt.m_iPosX, bt.m_iPosY, stSkEvent, this);
if (bRet) {
return;
}
}
}
void SkViewInput::show(SkShow* pSkShow, Sint64 iCurMTime) {
/**清空屏幕背景为黑色矩形**/
pSkShow->clear(0x00, 0x00, 0x00, 0xff);
/**游戏区域背景为蓝色矩形**/
SkRect backRect;
backRect.x = 0;
backRect.y = 0;
backRect.w = g_SP.m_iBaseWidth;
backRect.h = g_SP.m_iBaseHeight;
pSkShow->fillRec(&backRect, 0x00, 0x00, 0xff, 0xff);
/**返回按钮**/
pSkShow->drawButton(NULL, &m_backButton, NULL, iCurMTime);
/**绘制一个白矩形-文字输入区域**/
SkRect stSkRect;
stSkRect.x = m_iKeyboardX;
stSkRect.y = m_iKeyboardY;
stSkRect.w = m_strMaxLen + 10;
stSkRect.h = 80;
pSkShow->fillRec(&stSkRect, 0xff, 0xff, 0xff, 0xff);
/**绘制一个红色光标-每秒闪烁一次**/
if ((iCurMTime / 500) % 2 == 0) {
stSkRect.x = m_iKeyboardX + m_curWord.m_skSurface.m_w + 5;
#ifdef __WP8__
stSkRect.x += m_dotWord.m_skSurface.m_w*m_iDotNum;
#endif
stSkRect.y = m_iKeyboardY + 5;
stSkRect.w = 4;
stSkRect.h = 80 - 10;
pSkShow->fillRec(&stSkRect, 0xff, 0x00, 0x00, 0xff);
}
/**绘制输入**/
stSkRect.x = m_iKeyboardX + 2;
stSkRect.y = m_iKeyboardY + (80 - m_curWord.m_skSurface.m_h) / 2;
pSkShow->drawWord(NULL, &m_curWord, &stSkRect, iCurMTime);
/**绘制拼音**/
stSkRect.x = m_iKeyboardX;
stSkRect.y = m_iKeyboardY + 90;
pSkShow->drawWord(NULL, &m_pingyin_word, &stSkRect, iCurMTime);
/**绘制搜索到的中文字**/
for (int i = 0; i < (int) m_vctSearchButton.size(); i++) {
pSkShow->drawButton(NULL, m_vctSearchButton.at(i), NULL, iCurMTime);
}
/**绘制中英文切换按钮**/
if (m_bEnglish) {
stSkRect.x = m_bt_english.m_iPosX;
stSkRect.y = m_bt_english.m_iPosY;
stSkRect.w = m_bt_english.getWidth();
stSkRect.h = m_bt_english.getHeight();
pSkShow->fillRec(&stSkRect, 0xff, 0x00, 0xff, 0xff);
} else {
stSkRect.x = m_bt_chinese.m_iPosX;
stSkRect.y = m_bt_chinese.m_iPosY;
stSkRect.w = m_bt_chinese.getWidth();
stSkRect.h = m_bt_chinese.getHeight();
pSkShow->fillRec(&stSkRect, 0xff, 0x00, 0xff, 0xff);
}
pSkShow->drawButton(NULL, &m_bt_english, NULL, iCurMTime);
pSkShow->drawButton(NULL, &m_bt_chinese, NULL, iCurMTime);
m_keyboard.show(pSkShow, iCurMTime);
}
void SkViewInput::setShift() {
m_keyboard.m_iShift = 100 - m_keyboard.m_iShift;
}
void SkViewInput::run(Sint64 iCurMTime) {
}
void SkViewInput::resize() {
m_keyboard.resize();
}
void SkViewInput::setEnglish(bool bFlag) {
m_bEnglish = bFlag;
}
void SkViewInput::addInput(int iId, string sIn) {
if (m_bEnglish || iId == 999) {
if (m_vctStr.size() > 0) {
string sOld = m_vctStr.back();
sOld.append(sIn);
m_vctStr.push_back(sOld);
} else {
m_vctStr.push_back(sIn);
}
m_curWord.setStr(m_vctStr.back(), m_font_ch, 0x00, 0x00, 0x00, 0xff);
if (m_curWord.m_skSurface.m_w >= m_strMaxLen) {
if (m_vctStr.size() > 0) {
m_vctStr.pop_back();
}
if (m_vctStr.size() > 0) {
m_curWord.setStr(m_vctStr.back(), m_font_ch, 0x00, 0x00, 0x00,
0xff);
} else {
m_curWord.setStr("", m_font_ch, 0x00, 0x00, 0x00, 0xff);
}
}
refresh();
} else {
char c = sIn.at(0);
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
if (m_pingyin.length() < 6) {
m_pingyin.append(sIn.c_str());
m_pingyin.mytolower();
m_pingyin_word.setStr(string(m_pingyin.c_str()), m_font_ch,
0xff, 0x00, 0x00, 0xff);
doSearch(m_pingyin.c_str(), 0);
refresh();
}
} else {
if (m_vctStr.size() > 0) {
string sOld = m_vctStr.back();
sOld.append(sIn);
m_vctStr.push_back(sOld);
} else {
m_vctStr.push_back(sIn);
}
m_curWord.setStr(m_vctStr.back(), m_font_ch, 0x00, 0x00, 0x00,
0xff);
if (m_curWord.m_skSurface.m_w >= m_strMaxLen) {
if (m_vctStr.size() > 0) {
m_vctStr.pop_back();
}
if (m_vctStr.size() > 0) {
m_curWord.setStr(m_vctStr.back(), m_font_ch, 0x00, 0x00,
0x00, 0xff);
} else {
m_curWord.setStr("", m_font_ch, 0x00, 0x00, 0x00, 0xff);
}
}
refresh();
}
}
#ifdef __WP8__
int iNum = 0;
for (int i = m_curWord.m_str.length()-1; i >=0; i--) {
if (m_curWord.m_str.at(i) == ' ') {
iNum++;
} else {
break;
}
}
m_iDotNum = iNum;
#endif
}
void SkViewInput::delInput() {
if (m_pingyin.length() > 0) {
m_pingyin.setlen(m_pingyin.length() - 1);
m_pingyin_word.setStr(string(m_pingyin.c_str()), m_font_ch, 0xff, 0x00,
0x00, 0xff);
doSearch(m_pingyin.c_str(), 0);
} else {
if (m_vctStr.size() > 0) {
m_vctStr.pop_back();
}
if (m_vctStr.size() > 0) {
m_curWord.setStr(m_vctStr.back(), m_font_ch, 0x00, 0x00, 0x00,
0xff);
} else {
m_curWord.setStr("", m_font_ch, 0x00, 0x00, 0x00, 0xff);
}
}
#ifdef __WP8__
int iNum = 0;
for (int i = m_curWord.m_str.length()-1; i >=0; i--) {
if (m_curWord.m_str.at(i) == ' ') {
iNum++;
} else {
break;
}
}
m_iDotNum = iNum;
#endif
refresh();
}
void SkViewInput::doSearchPrevious() {
m_iSearchBegin -= m_iEachNumber;
if (m_iSearchBegin < 0) {
m_iSearchBegin = 0;
}
doSearch(m_pingyin.c_str(), m_iSearchBegin);
refresh();
}
void SkViewInput::doSearchNext() {
m_iSearchBegin += m_iEachNumber;
doSearch(m_pingyin.c_str(), m_iSearchBegin);
refresh();
}
void SkViewInput::doSearch(const char * pingyin, int iBegin) {
m_iSearchBegin = iBegin;
for (int i = 0; i < (int) m_vctSearchButton.size(); i++) {
SkButton * pBt = m_vctSearchButton.at(i);
delete pBt;
}
m_vctSearchButton.clear();
m_search.clear();
g_SkZiku.doSearch(pingyin, m_search);
vector < string > vctStr;
g_SkString.getVctStr(vctStr, m_search.c_str(), "|", true);
int iBeforeLen = 0;
//if (iBegin > 0)
{
SkButton * pBt = new SkButton;
{
pBt->m_iId = 1011;
pBt->m_sName = "<<-";
SkWord wordIn, wordOut, wordPressed;
wordIn.setStr(pBt->m_sName.c_str(), m_font_ch, 255, 0, 0, 255);
wordOut.setStr(pBt->m_sName.c_str(), m_font_ch, 0, 255, 0, 255);
wordPressed.setStr(pBt->m_sName.c_str(), m_font_ch, 255, 255, 0,
255);
pBt->setShow(wordIn.m_skSurface, wordOut.m_skSurface,
wordPressed.m_skSurface);
pBt->m_area.clear();
pBt->m_area.addPoint(0, 0);
pBt->m_area.addPoint(wordIn.m_skSurface.m_w, 0);
pBt->m_area.addPoint(wordIn.m_skSurface.m_w,
wordIn.m_skSurface.m_h);
pBt->m_area.addPoint(0, wordIn.m_skSurface.m_h);
pBt->m_bWord = true;
pBt->setPosition(m_iKeyboardX + 150, m_iKeyboardY + 90);
pBt->setFuncPressed(sk_button_keyboard_pressed);
iBeforeLen = wordIn.m_skSurface.m_w;
}
m_vctSearchButton.push_back(pBt);
}
int iTlen = m_iEachNumber;
for (int i = iBegin; i < iBegin + iTlen; i++) {
if (i < (int) vctStr.size()) {
SkButton * pBt = new SkButton;
{
pBt->m_iId = 999;
pBt->m_sName = vctStr.at(i);
SkWord wordIn, wordOut, wordPressed;
wordIn.setStr(vctStr.at(i).c_str(), m_font_ch, 255, 0, 0, 255);
wordOut.setStr(vctStr.at(i).c_str(), m_font_ch, 0, 255, 0, 255);
wordPressed.setStr(vctStr.at(i).c_str(), m_font_ch, 255, 255, 0,
255);
pBt->setShow(wordIn.m_skSurface, wordOut.m_skSurface,
wordPressed.m_skSurface);
pBt->m_area.clear();
pBt->m_area.addPoint(0, 0);
pBt->m_area.addPoint(wordIn.m_skSurface.m_w, 0);
pBt->m_area.addPoint(wordIn.m_skSurface.m_w,
wordIn.m_skSurface.m_h);
pBt->m_area.addPoint(0, wordIn.m_skSurface.m_h);
pBt->m_bWord = true;
pBt->setPosition(
m_iKeyboardX + 150 + 70 * (i - m_iSearchBegin)
+ iBeforeLen + 10, m_iKeyboardY + 90);
pBt->setFuncPressed(sk_button_keyboard_pressed);
}
m_vctSearchButton.push_back(pBt);
}
}
//if (iBegin + iTlen < (int) vctStr.size())
{
SkButton * pBt = new SkButton;
{
pBt->m_iId = 1012;
pBt->m_sName = "->>";
SkWord wordIn, wordOut, wordPressed;
wordIn.setStr(pBt->m_sName.c_str(), m_font_ch, 255, 0, 0, 255);
wordOut.setStr(pBt->m_sName.c_str(), m_font_ch, 0, 255, 0, 255);
wordPressed.setStr(pBt->m_sName.c_str(), m_font_ch, 255, 255, 0,
255);
pBt->setShow(wordIn.m_skSurface, wordOut.m_skSurface,
wordPressed.m_skSurface);
pBt->m_area.clear();
pBt->m_area.addPoint(0, 0);
pBt->m_area.addPoint(wordIn.m_skSurface.m_w, 0);
pBt->m_area.addPoint(wordIn.m_skSurface.m_w,
wordIn.m_skSurface.m_h);
pBt->m_area.addPoint(0, wordIn.m_skSurface.m_h);
pBt->m_bWord = true;
pBt->setPosition(m_iKeyboardX + 150 + 70 * iTlen + iBeforeLen + 20,
m_iKeyboardY + 90);
pBt->setFuncPressed(sk_button_keyboard_pressed);
}
m_vctSearchButton.push_back(pBt);
}
}
void SkViewInput::refresh() {
//防止闪屏
#ifndef __WP8__
this->show(&g_SkShow, g_SkGameTimer.m_siGameLastTime);
#endif
}
void sk_button_keyboard_pressed(void * pData, SkButton * pButton) {
SkViewInput * pView = (SkViewInput *) pData;
//g_SkComm.log("[%s][%d]key %d:%s", __FILE__, __LINE__, pButton->m_iId,
// pButton->m_sName.c_str());
if (pButton->m_iId == 49 || pButton->m_iId == 149) {
pView->setShift();
} else if (pButton->m_iId == 1001) {
pView->setEnglish(true);
} else if (pButton->m_iId == 1002) {
pView->setEnglish(false);
} else if (pButton->m_iId == 1011) {
pView->doSearchPrevious();
} else if (pButton->m_iId == 1012) {
pView->doSearchNext();
} else if (pButton->m_iId == 36 || pButton->m_iId == 136) {
pView->delInput();
} else if (pButton->m_iId == 37 || pButton->m_iId == 137) {
} else {
pView->addInput(pButton->m_iId, pButton->m_sName);
}
}
SkViewInput g_SkViewInput;
效果如下:
android 版本运行如下: