📄 keyboardwidget_internal.cpp
字号:
#include "keyboardwidget_internal.h"#include "atr.h"#include "icons.cpp"#include "util.h"#include <qapplication.h>#include <qcstring.h>#include <qimage.h>#include <qpainter.h>#include <stdio.h>#include <stdlib.h>#define SWAP(a, b) { a ^= b; b ^= a; a ^= b; } // be careful to swap only variables, not expressionsnamespace archos {static QImage key_dark;static QImage key_light;static QImage key_dark_flat;static QImage key_light_flat;static QImage icon_return;static QImage icon_shift;static QImage icon_caps;static QImage icon_left;static QImage icon_right;static QImage icon_back;static QImage icon_up;static QImage icon_up_blue;static QImage icon_up_disabled;static QImage icon_down;static QImage icon_down_blue;static QImage icon_down_disabled;static QPixmap *key_dark_lt = NULL, *key_dark_t = NULL, *key_dark_rt = NULL;static QPixmap *key_dark_l = NULL, *key_dark_m = NULL, *key_dark_r = NULL;static QPixmap *key_dark_lb = NULL, *key_dark_b = NULL, *key_dark_rb = NULL;static QPixmap *key_light_lt = NULL, *key_light_t = NULL, *key_light_rt = NULL;static QPixmap *key_light_l = NULL, *key_light_m = NULL, *key_light_r = NULL;static QPixmap *key_light_lb = NULL, *key_light_b = NULL, *key_light_rb = NULL;}using archos::wchar;archos::KeyboardWidgetInternal::KeyboardWidgetInternal(QWidget *parent) : QWidget( parent ) , m_layout( &layout_en ) , m_tgt( NULL ) , m_selection( 0 ) , m_selection_bak( 0 ) , m_modifier( None ) , m_ignore_event( false ){ setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Minimum ) ); setBackgroundColor( Qt::gray ); setBackgroundMode( QWidget::PaletteBackground ); QFont f = QApplication::font(); f.setPointSize( 16 ); f.setBold( true ); setFont( f ); if( key_dark.isNull() ) { key_dark.loadFromData( string_key_dark, sizeof(string_key_dark) ); key_light.loadFromData( string_key_light, sizeof(string_key_light) ); key_dark_flat.loadFromData( string_key_dark_flat, sizeof(string_key_dark_flat) ); key_light_flat.loadFromData( string_key_light_flat, sizeof(string_key_light_flat) ); icon_return.loadFromData( string_return, sizeof(string_return) ); icon_shift.loadFromData( string_shift, sizeof(string_shift) ); icon_caps.loadFromData( string_capslock, sizeof(string_capslock) ); icon_left.loadFromData( string_cursor_left, sizeof(string_cursor_left) ); icon_right.loadFromData( string_cursor_right, sizeof(string_cursor_right) ); icon_back.loadFromData( string_del, sizeof(string_del) ); icon_up.loadFromData( string_cursor_up, sizeof(string_cursor_up) ); icon_up_blue.loadFromData( string_cursor_up_blue, sizeof(string_cursor_up_blue) ); icon_down.loadFromData( string_cursor_down, sizeof(string_cursor_down) ); icon_down_blue.loadFromData( string_cursor_down_blue, sizeof(string_cursor_down_blue) ); icon_up_disabled.loadFromData( string_cursor_up_disabled, sizeof(string_cursor_up_disabled) ); icon_down_disabled.loadFromData( string_cursor_down_disabled, sizeof(string_cursor_down_disabled) ); } if( key_dark_lt == NULL ) { key_dark_lt = new QPixmap(); key_dark_lt->loadFromData( string_key_dark_lt, sizeof(string_key_dark_lt) ); key_dark_t = new QPixmap(); key_dark_t->loadFromData( string_key_dark_t, sizeof(string_key_dark_t ) ); key_dark_rt = new QPixmap(); key_dark_rt->loadFromData( string_key_dark_rt, sizeof(string_key_dark_rt) ); key_dark_l = new QPixmap(); key_dark_l->loadFromData( string_key_dark_l, sizeof(string_key_dark_l ) ); key_dark_m = new QPixmap(); key_dark_m->loadFromData( string_key_dark_m, sizeof(string_key_dark_m ) ); key_dark_r = new QPixmap(); key_dark_r->loadFromData( string_key_dark_r, sizeof(string_key_dark_r ) ); key_dark_lb = new QPixmap(); key_dark_lb->loadFromData( string_key_dark_lb, sizeof(string_key_dark_lb) ); key_dark_b = new QPixmap(); key_dark_b->loadFromData( string_key_dark_b, sizeof(string_key_dark_b ) ); key_dark_rb = new QPixmap(); key_dark_rb->loadFromData( string_key_dark_rb, sizeof(string_key_dark_rb) ); key_light_lt = new QPixmap(); key_light_lt->loadFromData( string_key_light_lt, sizeof(string_key_light_lt) ); key_light_t = new QPixmap(); key_light_t->loadFromData( string_key_light_t, sizeof(string_key_light_t ) ); key_light_rt = new QPixmap(); key_light_rt->loadFromData( string_key_light_rt, sizeof(string_key_light_rt) ); key_light_l = new QPixmap(); key_light_l->loadFromData( string_key_light_l, sizeof(string_key_light_l ) ); key_light_m = new QPixmap(); key_light_m->loadFromData( string_key_light_m, sizeof(string_key_light_m ) ); key_light_r = new QPixmap(); key_light_r->loadFromData( string_key_light_r, sizeof(string_key_light_r ) ); key_light_lb = new QPixmap(); key_light_lb->loadFromData( string_key_light_lb, sizeof(string_key_light_lb) ); key_light_b = new QPixmap(); key_light_b->loadFromData( string_key_light_b, sizeof(string_key_light_b ) ); key_light_rb = new QPixmap(); key_light_rb->loadFromData( string_key_light_rb, sizeof(string_key_light_rb) ); } reset();}archos::KeyboardWidgetInternal::~KeyboardWidgetInternal() {}void archos::KeyboardWidgetInternal::reset(){ m_layout = getLayout(); m_selection = m_layout->cols * 3 / 2 - 1; m_selection_bak = m_layout->cols - 2; m_modifier = None; if( m_layout->type == Touchscreen && getResolution() == RESOLUTION_WIDE_QVGA ) { setMinimumWidth( m_layout->cols * ( key_dark_flat.width() + 2 ) ); setMinimumHeight( m_layout->rows * ( key_dark_flat.height() + 0 ) + 2); } else { setMinimumWidth( m_layout->cols * ( key_dark.width() + 2 ) ); setMinimumHeight( m_layout->rows * ( key_dark.height() + 0 ) + 2); }}int archos::KeyboardWidgetInternal::heightForWidth( int w ) const{ return w / 3;}const archos::Layout* archos::KeyboardWidgetInternal::getLayout() const{ const Layout *res = NULL; char *locale = getenv( "LANG" ); if( strncmp( locale, "de_DE", 5 ) == 0 ) { res = ( getVideoMode() == LcdMode ) ? &layout_de : &layout_de_tv; } else if( strncmp( locale, "fr_FR", 5 ) == 0 ) { res = ( getVideoMode() == LcdMode ) ? &layout_fr : &layout_fr_tv; } else { res = ( getVideoMode() == LcdMode ) ? &layout_en : &layout_en_tv; } return res;}void archos::KeyboardWidgetInternal::setReceiver( QWidget *receiver ) { m_tgt = receiver;}bool archos::KeyboardWidgetInternal::isValidKey( wchar key ) const{ return key != Key_Invalid && key != Key_Empty && key != Key_Fused;}wchar archos::KeyboardWidgetInternal::getKey( int index, int modifier ) const{ wchar key = Key_Invalid; switch( modifier ) { case Shift : case Caps : if( m_layout->keys_shifted != NULL ) key = m_layout->keys_shifted[index]; break; case Alt : if( m_layout->keys_alt != NULL ) key = m_layout->keys_alt[index]; break; case AltGr : if( m_layout->keys_altgr != NULL ) key = m_layout->keys_altgr[index]; break; default : key = m_layout->keys[index]; break; } return key;}QString archos::KeyboardWidgetInternal::getKeyLabel( wchar key, QImage **icon, bool blue, bool disabled ) const{ *icon = NULL; switch( key ) { case Key_Escape : return atr( "Esc" ); case Key_Tab : return atr( "Tab" ); case Key_Enter : return atr( "Ok" ); case Key_Alt : return atr( "Alt" ); case Key_AltGr : return atr( "AltGr" ); case Key_Return : *icon = &icon_return; break; case Key_CapsLock : *icon = &icon_caps; break; case Key_Backspace : *icon = &icon_back; break; case Key_Shift : *icon = &icon_shift; break; case Key_Left : *icon = &icon_left; break; case Key_Right : *icon = &icon_right; break; case Key_Up : if( blue ) { *icon = disabled ? &icon_up_disabled : &icon_up_blue; } else { *icon = &icon_up; } break; case Key_Down : if( blue ) { *icon = disabled ? &icon_down_disabled : &icon_down_blue; } else { *icon = &icon_down; } break; default : { wchar buffer[] = { key, '\0' }; return QString::fromLatin1( (const char*) buffer ); } } return "";}void archos::KeyboardWidgetInternal::displayKeyLabel( QPainter *p, int index, int modifier, const QRect &area ) const{ wchar key = getKey( index, modifier ); if( key == Key_Invalid || key == Key_Empty ) return; int offset_modifier; if( m_layout->type == TV ) { offset_modifier = Shift; } else if( modifier == AltGr ) { offset_modifier = AltGr; } else { offset_modifier = Alt; } bool multilabel = true; if( modifier & offset_modifier ) { multilabel &= key != getKey( index, None ); } else if( offset_modifier == Alt && m_layout->keys_alt != NULL ) { multilabel &= key != getKey( index, Alt ); } else if( offset_modifier == Shift && m_layout->keys_shifted != NULL ) { multilabel &= key != getKey( index, Shift ); } if( modifier == offset_modifier && !multilabel ) return; bool transparent = !isValidKey( key ) || ( modifier != m_modifier && multilabel ); bool blue = ( modifier == Alt || modifier == AltGr || key == Key_Alt || key == Key_AltGr ); QColor color; if( blue ) { color = transparent ? QColor( 96, 96, 150 ) : QColor( 0, 0, 131 ); } else { color = transparent ? QColor( 96, 96, 96 ) : QColor( 0, 0, 0 ); } QImage *icon; QString label = getKeyLabel( key, &icon, blue, transparent ); if( icon != NULL ) { // draw key icon int xpos = area.x(); int ypos = area.y(); if( modifier == offset_modifier ) { xpos -= 6; ypos -= 4; } else { xpos += ( area.width() - icon->width() ) / 2; ypos += ( area.height() - icon->height() ) / 2 + 5; } p->drawImage( xpos, ypos, *icon ); } else { p->setPen( color ); if( modifier == offset_modifier ) { QRect ta = QRect( area.x() + 2, area.y() + 0, area.width() - 4, area.height() - 0 ); p->drawText( ta, Qt::AlignLeft | Qt::AlignTop, label ); } else { QRect ta = QRect( area.x(), area.y() + 7, area.width(), area.height() - 7 ); p->drawText( ta, Qt::AlignCenter, label ); } }}QRect archos::KeyboardWidgetInternal::displayButton( QPainter *p, int index ) const{ if( getKey( index, m_modifier ) == Key_Fused ) return QRect(); bool selected = ( index == m_selection ); QPixmap *plt = selected ? key_light_lt : key_dark_lt; QPixmap *pt = selected ? key_light_t : key_dark_t; QPixmap *prt = selected ? key_light_rt : key_dark_rt; QPixmap *pl = selected ? key_light_l : key_dark_l; QPixmap *pm = selected ? key_light_m : key_dark_m; QPixmap *pr = selected ? key_light_r : key_dark_r; QPixmap *plb = selected ? key_light_lb : key_dark_lb; QPixmap *pb = selected ? key_light_b : key_dark_b; QPixmap *prb = selected ? key_light_rb : key_dark_rb; QRect area = areaFor( index ); int l = area.x(); int t = area.y(); int mh = l + key_dark_lt->width(); int mv = t + key_dark_lt->height(); int r = l + area.width() - 1 - key_dark_rt->width(); int b = t + area.height() - 1 - key_dark_rt->height(); // draw corners p->drawPixmap( l, t, *plt ); p->drawPixmap( r, t, *prt ); p->drawPixmap( l, b, *plb ); p->drawPixmap( r, b, *prb ); // draw edges p->drawTiledPixmap( mh, t, r - mh, key_dark_t->height(), *pt ); p->drawTiledPixmap( mh, b, r - mh, key_dark_b->height(), *pb ); p->drawTiledPixmap( l, mv, key_dark_l->width(), b - mv, *pl ); p->drawTiledPixmap( r, mv, key_dark_r->width(), b - mv, *pr ); // draw center p->drawTiledPixmap( mh, mv, r - mh + 1, b - mv + 1, *pm ); return area;}void archos::KeyboardWidgetInternal::displayKey( QPainter *p, int index ) const{ wchar key = getKey( index, m_modifier ); if( key == Key_Empty ) return; // draw background QRect area = displayButton( p, index ); // draw labels// area = QRect( area.x() + xofs, area.y() + yofs, area.width() - 2 * xofs, area.height() - 2 * yofs ); if( m_layout->type == Touchscreen ) { displayKeyLabel( p, index, m_modifier & ~Alt & ~AltGr, area ); displayKeyLabel( p, index, ( m_modifier == AltGr ) ? AltGr : Alt, area ); } else { displayKeyLabel( p, index, m_modifier & ~Shift, area ); displayKeyLabel( p, index, Shift, area ); }}void archos::KeyboardWidgetInternal::paintEvent( QPaintEvent *evt ){ QRect area = evt->rect(); QPixmap pm( area.size() ); QPainter bp( &pm, this ); bp.fillRect( QRect(QPoint( 0, 0 ), area.size() ), backgroundColor() ); bp.translate( -area.x(), -area.y() ); for( int i = 0; i < m_layout->rows * m_layout->cols; i++ ) displayKey( &bp, i ); QPainter p( this ); p.drawPixmap( area.x(), area.y(), pm ); // Now disable background to avoid fickering setBackgroundMode(QWidget::NoBackground);}void archos::KeyboardWidgetInternal::handleOkPressed( bool autorepeat ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -