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

📄 pinyinframe.cpp

📁 对MurphyPinyin的改进版
💻 CPP
📖 第 1 页 / 共 3 页
字号:
".a.a.a.a.",
".aaa..aa.",
".a...aaa.",
".........",
"...a.....",
".aaa.aaa.",
".a.a.a.a.",
".aaa.a.a."};
/* XPM */
static const char * const expand_xpm[]={
"4 9 2 1",
"a c #408040",
". c None",
"a...",
"aa..",
"aaa.",
"aaaa",
"aaaa",
"aaaa",
"aaa.",
"aa..",
"a..."};
/* XPM */
#ifdef USE_SMALL_BACKSPACE
static const char * const backspace_xpm[]={
"9 9 2 1",
"a c #000000",
". c None",
".........",
".........",
"...a.....",
"..aa.....",
".aaaaaaaa",
"..aa.....",
"...a.....",
".........",
"........."};
#else
static const char * const backspace_xpm[]={
"21 9 2 1",
"a c #000000",
". c None",
".....................",
".....................",
".....aaa..a..........",
".a...a..a.a.a.aaa.aaa",
"aaaa.aaa..aa..aa..a.a",
".a...a..a.aaa..aa.a.a",
".....aaaa.a.a.aaa.aa.",
"..................a..",
"....................."};
#endif
/* XPM */
static const char * const escape_xpm[]={
"9 9 2 1",
"a c #000000",
". c None",
".........",
".........",
".aa.aa.aa",
".a..a..a.",
".aa.aa.a.",
".a...a.a.",
".aa.aa.aa",
".........",
"........."};


enum { BSCode = 0x80, TabCode, CapsCode, RetCode, 
       ShiftCode, CtrlCode, AltCode, SpaceCode, BackSlash,
       UpCode, LeftCode, DownCode, RightCode, Blank, Expand,
       Opti, ResetDict,
       Divide, Multiply, Add, Subtract, Decimal, Equal,
       Percent, Sqrt, Inverse, Escape };

typedef struct SpecialMap {
    int qcode;
    ushort unicode;
    const char * label;
    const char * const *xpm;
};


static const SpecialMap specialM[] = {
    {	Qt::Key_Backspace,	8,	"<",     backspace_xpm },
    {	Qt::Key_Tab,		9,	"Tab",   NULL }, // No tr
    {	Qt::Key_CapsLock,	0xffff,	"Caps",  NULL }, // No tr
    {	Qt::Key_Return,		13,	"Ret",   NULL }, // No tr
    {	Qt::Key_Shift,		0xffff,	"Shift", NULL }, // No tr
    {	Qt::Key_Control,	0xffff,	"Ctrl",  NULL }, // No tr
    {	Qt::Key_Alt,		0xffff,	"Alt",   NULL }, // No tr
    {	Qt::Key_Space,		' ',	"",      NULL },
    {	BackSlash,		43,	"\\",    NULL },

    // Need images?
    {	Qt::Key_Up,		0xffff,	"^",     uparrow_xpm },
    {	Qt::Key_Left,		0xffff,	"<",     leftarrow_xpm },
    {	Qt::Key_Down,		0xffff,	"v",     downarrow_xpm },
    {	Qt::Key_Right,		0xffff,	">",     rightarrow_xpm },
    {	Qt::Key_Insert,		0xffff,	"I",     insert_xpm },
    {	Qt::Key_Home,		0xffff,	"H",     home_xpm },
    {	Qt::Key_PageUp,		0xffff,	"U",     pageup_xpm },
    {	Qt::Key_End,		0xffff,	"E",     end_xpm },
    {	Qt::Key_Delete,		0xffff,	"X",     delete_xpm },
    {	Qt::Key_PageDown,	0xffff,	"D",     pagedown_xpm },
    {	Blank,			0,	" ",     NULL },
    {	Expand,			0xffff,	"->",    expand_xpm },
    {	Opti,			0xffff,	"#",     NULL },
    {	ResetDict,		0xffff,	"R",     NULL },
   
    // number pad stuff
    {	Divide,			0,	"/",     NULL },
    {	Multiply,		0,	"*",     NULL },
    {	Add,			0,	"+",     NULL },
    {	Subtract,		0,	"-",     NULL },
    {	Decimal,		0,	".",     NULL },
    {	Equal,			0,	"=",     NULL },
    {	Percent,		0,	"%",     NULL },
    {	Sqrt,			0,	"^1/2",	 NULL },
    {	Inverse,		0,	"1/x",	 NULL },

    {	Escape,			27,	"ESC",	 escape_xpm }
};


/*
  return scancode and width of first key in row \a j if \a j >= 0,
  or next key on current row if \a j < 0.
  
*/
int useOptiKeys=0;
int getKey( int &w, int j ) {
    static const uchar *row = 0;
    static int key_i = 0;
    static int scancode = 0;
    static int half = 0;
    
    if ( j >= 0 && j < 5 ) {
	if (useOptiKeys)
    	    row = keyboard_opti[j];
	else
    	    row = keyboard_standard[j];
	half=0;
    }

    if ( !row || !*row ) {
	return 0;    
    } else if ( row[1] >= 0x80 ) {
	scancode = row[1];
	w = (row[0] * w + (half++&1)) / 2;
	row += 2;
	return scancode;
    } else if ( key_i <= 0 ) {
	key_i = row[0]/2;
	scancode = row[1];
    }
    key_i--;
    if ( key_i <= 0 )
	row += 2;
    return scancode++;
}

static int keycode( int i2, int j, const uchar **keyboard )
{
    if ( j <0 || j >= 5 )
        return 0;
                                                                                
    const uchar *row = keyboard[j];
                                                                                
    while ( *row && *row <= i2 ) {
        i2 -= *row;
        row += 2;
    }
                                                                                
    if ( !*row ) return 0;
                                                                                
    int k;
    if ( row[1] >= 0x80 ) {
        k = row[1];
    } else {
        k = row[1]+i2/2;
    }
                                                                                
    return k;
}

    
/*
  Draw the keyboard.

  If key >= 0, only the specified key is drawn.
*/
void QPinyinFrame::drawKeyboard( QPainter &p, int key )
{
    const bool threeD = FALSE;
    const QColorGroup& cg = colorGroup();
    QColor keycolor = // cg.background();
		    	QColor(240,240,230); // Beige!
    QColor keycolor_pressed = cg.mid();
    QColor keycolor_lo = cg.dark();
    QColor keycolor_hi = cg.light();
    QColor textcolor = QColor(0,0,0); // cg.text();

    int margin = threeD ? 1 : 0;
    
//    p.fillRect( 0, , kw-1, keyHeight-2, keycolor_pressed );

    for ( int j = 0; j < 5; j++ ) {
	int y = j * keyHeight + PickHeight + 1;// 1;
	int x = xoffs;
	int kw = defaultKeyWidth;
	int k= getKey( kw, j );
	while ( k ) {
	    if ( key < 0 || k == key ) {
		QString s;
		bool pressed = (k == pressedKey);
		bool blank = (k == 0223);
		const char * const * xpm = NULL;
		
		if ( k >= 0x80 ) {
		    s = specialM[k - 0x80].label;

		    xpm = specialM[k - 0x80].xpm;
			
		    if ( k == ShiftCode ) {
			pressed = shift;
		    } else if ( k == CapsCode ) {
			pressed = lock;
		    } else if ( k == CtrlCode ) {
			pressed = ctrl;
		    } else if ( k == AltCode ) {
			pressed = alt;
		    } 
		} else {
#if defined(Q_WS_QWS) || defined(_WS_QWS_)
/*
		    s = QChar( shift^lock ? QWSServer::keyMap()[k].shift_unicode : 
			       QWSServer::keyMap()[k].unicode);
*/
		    // ### Fixme, bad code, needs improving, whole thing needs to
		    // be re-coded to get rid of the way it did things with scancodes etc
		    char shifted = k;
		    if ( !isalpha( k ) ) {
			for ( unsigned i = 0; i < sizeof(shiftMap)/sizeof(ShiftMap); i++ )
			    if ( shiftMap[i].normal == k )
				shifted = shiftMap[i].shifted;
		    } else {
			shifted = toupper( k );
		    }
		    s = QChar( shift^lock ? shifted : k );
#endif
		}

		if (!blank) {
		    if ( pressed )
			p.fillRect( x+margin, y+margin, kw-margin, keyHeight-margin-1, keycolor_pressed );
		    else
			p.fillRect( x+margin, y+margin, kw-margin, keyHeight-margin-1, keycolor );

		    if ( threeD ) {
			p.setPen(pressed ? keycolor_lo : keycolor_hi);
			p.drawLine( x, y+1, x, y+keyHeight-2 );
			p.drawLine( x+1, y+1, x+1, y+keyHeight-3 );
			p.drawLine( x+1, y+1, x+1+kw-2, y+1 );
		    } else if ( j == 0 ) {
			p.setPen(pressed ? keycolor_hi : keycolor_lo);
			p.drawLine( x, y, x+kw, y );
		    }

		    // right
		    p.setPen(pressed ? keycolor_hi : keycolor_lo);
		    p.drawLine( x+kw-1, y, x+kw-1, y+keyHeight-2 );

		    if ( threeD ) {
			p.setPen(keycolor_lo.light());
			p.drawLine( x+kw-2, y+keyHeight-2, x+kw-2, y+1 );
			p.drawLine( x+kw-2, y+keyHeight-2, x+1, y+keyHeight-2 );
		    }

		    if (xpm) {
			p.drawPixmap( x + 1, y + 2, QPixmap((const char**)xpm) );
		    } else {
    			p.setPen(textcolor);
			p.drawText( x - 1, y, kw, keyHeight-2, AlignCenter, s );
		    }
	    
		    if ( threeD ) {
			p.setPen(keycolor_hi);
			p.drawLine( x, y, x+kw-1, y );
		    }

		    // bottom
		    p.setPen(keycolor_lo);
		    p.drawLine( x, y+keyHeight-1, x+kw-1, y+keyHeight-1 );
	    
		} else {
		    p.fillRect( x, y, kw, keyHeight, cg.background() );
		}
	    }

	    x += kw;
	    kw = defaultKeyWidth;
	    k = getKey( kw ,-1);
	}
    }
}


void QPinyinFrame::clearHighlight()
{
    if (m_bShowKeyboard&&( pressedKey >= 0) ) {
	int tmp = pressedKey;
	pressedKey = -1;
	QPainter p(this);
	drawKeyboard( p, tmp );
    }
}

void QPinyinFrame::timerEvent(QTimerEvent*e)
{
    if ( e->timerId() == pressTid ) {
	killTimer(pressTid);
        pressTid = 0;
        if ( !pressed )
            clearHighlight();
    }
}

void QPinyinFrame::repeat()
{
    repeatTimer->start( 150 );
    if(m_bEnglishMode) {
    	emit key( unicode, qkeycode, modifiers, true, true );
    } else
	GetKey(unicode,qkeycode);
}

void QPinyinFrame::mousePressEvent(QMouseEvent *e) 
{
    if(!m_bShowKeyboard) return;
    printX86("(%d,%d)-height=%d\n",e->x(),e->y(),PickHeight);
    if(e->y()<=PickHeight) return;                                                                        
    clearHighlight(); // typing fast?

    int i2 = ((e->x() - xoffs) * 2) / defaultKeyWidth;
    int j = (e->y() - PickHeight) / keyHeight;
                                                                                
    int k = keycode( i2, j, (const uchar **)((useOptiKeys) ? keyboard_opti : keyboard_standard) );
    bool need_repaint = FALSE;
    unicode = -1;
    qkeycode = 0;
    printX86("k=%d\n",k);
    if ( k >= 0x80 ) {
        if ( k == ShiftCode ) {
            shift = !shift;
	    if(!m_bEnglishMode)
	    	GetKey(unicode,Qt::Key_Shift);
            need_repaint = TRUE;
        } else if ( k == AltCode ){
            alt = !alt;
            need_repaint = TRUE;
        } else if ( k == CapsCode ) {
            lock = !lock;
            need_repaint = TRUE;
        } else if ( k == CtrlCode ) {
            ctrl = !ctrl;
	     need_repaint = TRUE;
        } else if ( k == 0224 /* Expand */ ) {
            useLargeKeys = !useLargeKeys;
            resizeEvent(0);
            repaint( TRUE ); // need it to clear first
        } else if ( k == 0225 /* Opti/Toggle */ ) {
            useOptiKeys = !useOptiKeys;
            resizeEvent(0);
            repaint( TRUE ); // need it to clear first
        } else {
            qkeycode = specialM[ k - 0x80 ].qcode;
            unicode = specialM[ k - 0x80 ].unicode;
        }
    } else {
        //due to the way the keyboard is defined, we know that
        //k is within the ASCII range, and can be directly mapped to
        //a qkeycode; except letters, which are all uppercase
        qkeycode = toupper(k);
        if ( shift^lock ) {
            if ( !isalpha( k ) ) {
            for ( unsigned i = 0; i < sizeof(shiftMap)/sizeof(ShiftMap); i++ )
                if ( shiftMap[i].normal == k ) {
                    unicode = shiftMap[i].shifted;
           qkeycode = unicode;
                    break;
                }
            } else {
                unicode = toupper( k );
            }
        } else {
            unicode = k;
        }
    }
    if  ( unicode != -1 ) {
        if ( ctrl && unicode >= 'a' && unicode <= 'z' )
            unicode = unicode - 'a'+1;
        modifiers = (shift ? Qt::ShiftButton : 0) | (ctrl ? Qt::ControlButton :
0) |
                  (alt ? Qt::AltButton : 0);
#if defined(Q_WS_QWS) || defined(_WS_QWS_)
	if(m_bEnglishMode) {
	        emit key( unicode, qkeycode, modifiers, true, false );
	} else 
		GetKey(unicode,qkeycode);
        repeatTimer->start( 200 );
#endif
        need_repaint = shift || alt || ctrl;
        shift = alt = ctrl = FALSE;
	/*KeyboardConfig *dc = picks->dc;
                                                                                
        if (dc) {
            if (qkeycode == Qt::Key_Backspace) {
                dc->input.remove(dc->input.last()); // remove last input
                dc->decBackspaces();
            } else if ( k == 0226 || qkeycode == Qt::Key_Return ||
                        qkeycode == Qt::Key_Space ||
                        QChar(unicode).isPunct() ) {
                dc->input.clear();
                dc->resetBackspaces();
            } else {
                dc->add(QString(QChar(unicode)));
                dc->incBackspaces();
            }
        }*/
    }
    pressedKey = k;
    if ( need_repaint ) {
        repaint( FALSE );
    } else {
        QPainter p(this);
        drawKeyboard( p, pressedKey );
    }
    pressTid = startTimer(80);
    pressed = TRUE;
}


/*QSize QPinyinFrame::sizeHint() const
{
    QFontMetrics fm=fontMetrics();
    int keyHeight = fm.lineSpacing()+2;

    if (useOptiKeys)
    	keyHeight += 1;
    
    return QSize( 320, keyHeight * 5 + 32);
}*/


/*
 * Revision history
 * 
 * $Log: PinyinFrame.cpp,v $
 * Revision 1.7  2004/07/31 17:20:19  Lu Mu
 * support chinese punctuations
 *
 * Revision 1.6  2004/07/20 11:26:05  Lu Mu
 * (1)phrase frequency
 * (2)self define phrase
 *
 * Revision 1.5  2004/07/17 07:11:54  Lu Mu
 * 1)phrase support
 * 2)candidates sequence number,changed to 1,2,..,9,0
 * 3)space key to select first candidate
 *
 * Revision 1.4  2004/07/15 13:56:17  Lu Mu
 * fixed : hanzi candidates overlapped by system task bar while default font is not efont
 *
 * Revision 1.3  2004/07/10 16:58:11  Lu Mu
 * bug fix of displaying hanzi problem after the first page
 *
 * Revision 1.2  2004/07/10 15:02:23  Lu Mu
 * v0.0.1 released
 * TODO: phase support
 *
 * Revision 1.1.1.1  2004/07/07 16:24:13  Lu Mu
 * Created
 *
 *
 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -