Changeset 858

Show
Ignore:
Timestamp:
06/04/07 05:14:39 (2 years ago)
Author:
ok_computer
Message:

Adding SDL key event handling to sdl_store widget. SDL key events are now forwarded onto Qt.

Location:
trunk/jahwidgets/src/qt3/widgets
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/jahwidgets/src/qt3/widgets/sdl_store.cpp

    r741 r858  
    1010// qt 
    1111#include <qlayout.h> 
     12#include <qapplication.h> 
     13#include <qtimer.h> 
    1214 
    1315// oml 
     
    2022namespace jahwidgets { namespace qt3 { 
    2123 
     24/// An observer used to forward SDL key events to Qt 
     25class sdl_key_observer : public QObject, public pcos::observer 
     26{ 
     27        Q_OBJECT 
     28 
     29 public: 
     30        sdl_key_observer( pcos::property keydown_prop, pcos::property keymod_prop, QWidget* top_level ) 
     31                : m_keydown( keydown_prop ), 
     32                m_keymod( keymod_prop ), 
     33                m_toplevel( top_level ), 
     34                m_count( 0 ) 
     35                { 
     36                        connect( &m_timer, SIGNAL(timeout()), SLOT(postEvent()) ); 
     37                } 
     38 
     39        void updated( pcos::isubject* )  
     40        { 
     41                // If we have a valid key then post a key event 
     42                if ( m_keydown.value<int>() > 0 )  
     43                { 
     44                        m_count = 0; 
     45                        postEvent(); 
     46                } 
     47                else { 
     48                        // Stop the timer now the key has gone up 
     49                        // TODO: Could post a KeyRelease event if anyone was interested... 
     50                        m_timer.stop(); 
     51                } 
     52        } 
     53 
     54protected slots: 
     55        void postEvent() 
     56        { 
     57                if ( m_keydown.value<int>() > 0 ) { 
     58                        // Forward the event onto Qt :) 
     59                        int ascii = 0; 
     60                        QString str; 
     61                        int keydown = m_keydown.value<int>(); 
     62                        if ( keydown <= 127 ) { 
     63                                ascii = keydown; 
     64                                str = char(ascii); 
     65                        } 
     66 
     67                        qApp->postEvent( m_toplevel, 
     68                                                         new QKeyEvent( QEvent::KeyPress,  
     69                                                                                        map_sdlkey_to_qt( m_keydown.value<int>() ), 
     70                                                                                        ascii, 
     71                                                                                        map_sdlmod_to_qt( m_keymod.value<int>() ), 
     72                                                                                        QString::null 
     73                                                                                        ) 
     74                                                         ); 
     75 
     76                        // SDL doesn't support repeat key events, so to simulate a repeat we use a timer 
     77                        if ( m_count == 0 ) { 
     78                                // The first timeout is longer to prevent repeats from slow keypresses 
     79                                m_timer.start( 500, true ); // ms, single shot 
     80                        } 
     81                        else if ( !m_timer.isActive() ) { 
     82                                m_timer.start( 100, false ); // ms, repeat 
     83                        } 
     84                        ++m_count; 
     85                } 
     86        } 
     87 
     88 private: 
     89        // Converts an SDL key code into a Qt key code 
     90        int map_sdlkey_to_qt( int sdl_key ) const 
     91        { 
     92                // SDL uses the std ascii range for keys 0 - 255 
     93                // Qt expects all letters to be UPPERCASE 
     94                if ( sdl_key <= 127 ) { 
     95                        if ( sdl_key >= 'a' && sdl_key <= 'z' ) 
     96                                return sdl_key - 32; 
     97                        else 
     98                                return sdl_key; 
     99                } 
     100 
     101                // Above 127 SDL uses custom codes. We convert only a few here 
     102                switch ( sdl_key ) { 
     103                        /* Arrows + Home/End pad */ 
     104                case 273: 
     105                        return Qt::Key_Up; 
     106 
     107                case 274: 
     108                        return Qt::Key_Down; 
     109 
     110                case 275: 
     111                        return Qt::Key_Right; 
     112 
     113                case 276: 
     114                        return Qt::Key_Left; 
     115 
     116                case 278: 
     117                        return Qt::Key_Home; 
     118 
     119                case 279: 
     120                        return Qt::Key_End; 
     121 
     122                case 280: 
     123                        return Qt::Key_PageUp; 
     124 
     125                case 281: 
     126                        return Qt::Key_PageDown; 
     127 
     128                default: 
     129                        qWarning( "Unhandled sdl key: %d", sdl_key ); 
     130                } 
     131 
     132                return 0; 
     133        } 
     134 
     135        int map_sdlmod_to_qt( int sdl_mod ) const 
     136        { 
     137                static const int SDL_KMOD_SHIFT = (0x0001 | 0x0002);  
     138                static const int SDL_KMOD_CTRL = (0x0040 | 0x0080); 
     139                static const int SDL_KMOD_ALT   = (0x0100 | 0x0200); 
     140                static const int SDL_KMOD_META = (0x0400 | 0x0800); 
     141 
     142                // ignore no modifier 
     143                if ( sdl_mod == 0 )  
     144                        return 0; 
     145 
     146                if ( sdl_mod & SDL_KMOD_CTRL )  
     147                        return Qt::ControlButton; 
     148                else if ( sdl_mod &  SDL_KMOD_SHIFT ) 
     149                        return Qt::ShiftButton; 
     150                else if ( sdl_mod & SDL_KMOD_ALT ) 
     151                        return Qt::AltButton; 
     152                else if ( sdl_mod & SDL_KMOD_META ) 
     153                        return Qt::MetaButton; 
     154                else 
     155                        qWarning( "Unhandled sdl modifier: %d", sdl_mod ); 
     156 
     157                return 0; 
     158        } 
     159 
     160        pcos::property m_keydown, m_keymod; 
     161        QWidget* m_toplevel; 
     162        QTimer m_timer; 
     163        int m_count; 
     164}; 
     165 
    22166sdl_store::sdl_store( QWidget* w, const char* name ) 
    23167    : QWidget( w, name, Qt::WNoAutoErase ) 
     
    34178    pcos::property width = props.get_property_with_string( "width" ); 
    35179    pcos::property height = props.get_property_with_string( "height" ); 
    36     if ( !wid.valid() || !width.valid() || !height.valid() ) 
     180 
     181        // We need to catch SDL key events and forward them onto Qt 
     182    pcos::property keydown = props.get_property_with_string( "keydown" ); 
     183    pcos::property keymod = props.get_property_with_string( "keymod" ); 
     184 
     185    if ( !wid.valid() || !width.valid() || !height.valid()  
     186                 || !keydown.valid() || !keymod.valid() ) 
    37187    { 
    38188                qWarning( "sdl_store::init: failed to find all required properties" ); 
     
    45195    height.set( this->height() ); 
    46196 
     197        // Attach our key observer to forward key events onto Qt 
     198        m_keyobserver = boost::shared_ptr< pcos::observer >(  
     199                                                 new sdl_key_observer( keydown, keymod, this->topLevelWidget() )  
     200                                                 ); 
     201        keydown.attach( m_keyobserver ); 
     202        keydown.set_always_notify( true ); 
     203 
    47204    if ( parentWidget() && parentWidget()->layout() ) 
    48205                parentWidget()->layout()->invalidate(); 
     
    68225    pcos::property height = props.get_property_with_string( "height" ); 
    69226     
    70     qDebug( "sdl_store::minimumSizeHint: (%i, %i)", width.value< int >(), height.value< int >() ); 
    71      
    72227    return QSize( width.value< int >(), height.value< int >() ); 
    73228} 
     
    95250    height.set( e->size().height() ); 
    96251 
     252        /* 
    97253    qDebug( "sdl_store::resizeEvent: (%i, %i)->(%i, %i)[%i, %i]",  
    98254                        e->oldSize().width(), e->oldSize().height(), 
    99255                        e->size().width(), e->size().height(), 
    100256                        width.value<int>(), height.value<int>() ); 
     257        */ 
    101258} 
    102259 
    103260} } 
     261 
     262#include "sdl_store.moc" 
  • trunk/jahwidgets/src/qt3/widgets/sdl_store.hpp

    r732 r858  
    1919#include <openmedialib/ml/frame.hpp> 
    2020 
     21#include <openpluginlib/pl/pcos/property.hpp> 
     22#include <openpluginlib/pl/pcos/observer.hpp> 
     23 
    2124 
    2225namespace ml = olib::openmedialib::ml; 
     26namespace pcos = olib::openpluginlib::pcos; 
    2327 
    2428namespace jahwidgets { namespace qt3 { 
     
    4347private: 
    4448        ml::store_type_ptr store_; 
     49        boost::shared_ptr< pcos::observer > m_keyobserver; 
    4550}; 
    4651 
  • trunk/jahwidgets/src/qt3/widgets/widgets_vc80.vcproj

    r840 r858  
    11601160                                </FileConfiguration> 
    11611161                        </File> 
     1162                        <File 
     1163                                RelativePath=".\tmp\moc\sdl_store.moc" 
     1164                                > 
     1165                                <FileConfiguration 
     1166                                        Name="Debug|Win32" 
     1167                                        > 
     1168                                        <Tool 
     1169                                                Name="VCCustomBuildTool" 
     1170                                                Description="Moc&apos;ing sdl_store.cpp..." 
     1171                                                CommandLine="$(QTDIR)\bin\moc.exe sdl_store.cpp -o tmp\moc\sdl_store.moc&#x0D;&#x0A;" 
     1172                                                AdditionalDependencies="$(QTDIR)\bin\moc.exe" 
     1173                                                Outputs="tmp\moc\sdl_store.moc" 
     1174                                        /> 
     1175                                </FileConfiguration> 
     1176                                <FileConfiguration 
     1177                                        Name="Release|Win32" 
     1178                                        > 
     1179                                        <Tool 
     1180                                                Name="VCCustomBuildTool" 
     1181                                                Description="Moc&apos;ing sdl_store.cpp..." 
     1182                                                CommandLine="$(QTDIR)\bin\moc.exe sdl_store.cpp -o tmp\moc\sdl_store.moc&#x0D;&#x0A;" 
     1183                                                AdditionalDependencies="$(QTDIR)\bin\moc.exe" 
     1184                                                Outputs="tmp\moc\sdl_store.moc" 
     1185                                        /> 
     1186                                </FileConfiguration> 
     1187                        </File> 
    11621188                </Filter> 
    11631189        </Files>