VirtualBox

Changeset 78661 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 22, 2019 1:24:02 PM (6 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:6143. Implementing toggleable modifier keys.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/softkeyboard/UISoftKeyboard.cpp

    r78635 r78661  
    3434#include "CEventSource.h"
    3535
     36enum UIKeyState
     37{
     38    UIKeyState_NotPressed,
     39    UIKeyState_Pressed,
     40    UIKeyState_Locked,
     41    UIKeyState_Max
     42};
     43
     44enum UIKeyType
     45{
     46    UIKeyType_SingleState,
     47    UIKeyType_DualState,
     48    UIKeyType_TriState,
     49    UIKeyType_Max
     50};
     51
    3652struct SoftKeyboardKey
    3753{
    38     int      m_iWidth;
    39     QString  m_strLabel;
    40     LONG     m_scanCode;
    41     LONG     m_scanCodePrefix;
     54    int       m_iWidth;
     55    QString   m_strLabel;
     56    LONG      m_scanCode;
     57    LONG      m_scanCodePrefix;
     58    int       m_iSpaceAfter;
     59    UIKeyType m_enmType;
    4260};
    4361
     
    4563{
    4664    int m_iHeight;
     65    int m_iStartingSpace;
    4766    QList<SoftKeyboardKey> m_keys;
    4867};
     
    6786
    6887    bool parseRow(SoftKeyboardLayout &layout);
     88    bool parseSpace(SoftKeyboardRow &row);
    6989    bool parseKey(SoftKeyboardRow &row);
    7090    QXmlStreamReader m_xmlReader;
     
    80100    Q_OBJECT;
    81101
     102signals:
     103
     104    void sigStateChanged();
     105
    82106public:
    83107
     
    93117    LONG scanCodePrefix() const;
    94118
     119    void setSpaceAfter(int iSpace);
     120    int spaceAfter() const;
     121
     122    void setType(UIKeyType enmType);
     123    UIKeyType type() const;
     124
     125    UIKeyState state() const;
    95126    QVector<LONG> scanCodeWithPrefix() const;
    96 
    97127    void updateFontSize(float multiplier);
    98128
     129    void release();
     130
     131protected:
     132
     133    virtual void mousePressEvent(QMouseEvent *pEvent) /* override */;
     134
    99135private:
     136
     137    void updateState(bool fPressed);
     138    void updateBackground();
    100139
    101140    int   m_iWidth;
    102141    int   m_iDefaultPixelSize;
    103142    int   m_iDefaultPointSize;
     143    int   m_iSpaceAfter;
    104144    LONG  m_scanCode;
    105145    LONG  m_scanCodePrefix;
     146    UIKeyType m_enmType;
     147    UIKeyState m_enmState;
     148    QPalette     m_defaultPalette;
    106149};
    107150
     
    156199    layout.m_rows.append(SoftKeyboardRow());
    157200    SoftKeyboardRow &row = layout.m_rows.last();
     201    row.m_iHeight = 0;
     202    row.m_iStartingSpace = 0;
    158203    while (m_xmlReader.readNextStartElement())
    159204    {
    160205        if (m_xmlReader.name() == "key")
    161206            parseKey(row);
     207        else if (m_xmlReader.name() == "space")
     208            parseSpace(row);
    162209        else if (m_xmlReader.name() == "height")
    163210            row.m_iHeight = m_xmlReader.readElementText().toInt();
     
    168215}
    169216
     217bool UIKeyboardLayoutReader::parseSpace(SoftKeyboardRow &row)
     218{
     219    while (m_xmlReader.readNextStartElement())
     220    {
     221        if (m_xmlReader.name() == "width")
     222        {
     223            int iSpace = m_xmlReader.readElementText().toInt();
     224            /* Find the key that comes before this space (if any): */
     225            if (!row.m_keys.isEmpty())
     226                row.m_keys.back().m_iSpaceAfter = iSpace;
     227            /* If there are no keys yet, start the row with a space: */
     228            else
     229                row.m_iStartingSpace = iSpace;
     230        }
     231        else
     232            m_xmlReader.skipCurrentElement();
     233    }
     234    return true;
     235}
     236
    170237bool UIKeyboardLayoutReader::parseKey(SoftKeyboardRow &row)
    171238{
     
    174241    key.m_scanCode = 0;
    175242    key.m_scanCodePrefix = 0;
     243    key.m_iSpaceAfter = 0;
     244    key.m_enmType = UIKeyType_SingleState;
     245
    176246    while (m_xmlReader.readNextStartElement())
    177247    {
     
    201271                key.m_scanCodePrefix = 0;
    202272        }
     273        else if (m_xmlReader.name() == "type")
     274        {
     275            QString strType = m_xmlReader.readElementText();
     276            if (strType == "tristate")
     277                key.m_enmType = UIKeyType_TriState;
     278            else if (strType == "dualstate")
     279                key.m_enmType = UIKeyType_DualState;
     280        }
    203281        else
    204282            m_xmlReader.skipCurrentElement();
     
    214292    :QToolButton(pParent)
    215293    , m_iWidth(1)
     294    , m_iSpaceAfter(0)
     295    , m_scanCode(0)
     296    , m_scanCodePrefix(0)
     297    , m_enmType(UIKeyType_SingleState)
     298    , m_enmState(UIKeyState_NotPressed)
    216299{
    217300    m_iDefaultPointSize = font().pointSize();
    218301    m_iDefaultPixelSize = font().pixelSize();
     302    m_defaultPalette = palette();
    219303}
    220304
     
    247331{
    248332    return m_scanCodePrefix;
     333}
     334
     335void UISoftKeyboardKey::setSpaceAfter(int iSpace)
     336{
     337    m_iSpaceAfter = iSpace;
     338}
     339
     340int UISoftKeyboardKey::spaceAfter() const
     341{
     342    return m_iSpaceAfter;
     343}
     344
     345void UISoftKeyboardKey::setType(UIKeyType enmType)
     346{
     347    m_enmType = enmType;
     348}
     349
     350UIKeyType UISoftKeyboardKey::type() const
     351{
     352    return m_enmType;
     353}
     354
     355UIKeyState UISoftKeyboardKey::state() const
     356{
     357    return m_enmState;
    249358}
    250359
     
    265374}
    266375
    267 /*********************************************************************************************************************************
    268 *   UISoftKeyboardRow implementation.                                                                                  *
     376void UISoftKeyboardKey::release()
     377{
     378    updateState(false);
     379}
     380
     381void UISoftKeyboardKey::mousePressEvent(QMouseEvent *pEvent)
     382{
     383    QToolButton::mousePressEvent(pEvent);
     384    updateState(true);
     385}
     386
     387// void UISoftKeyboardKey::mouseReleaseEvent(QMouseEvent *pEvent)
     388// {
     389//     if (m_enmType == UIKeyType_SingleState)
     390//     {
     391//         QToolButton::mouseReleaseEvent(pEvent);
     392//         setState(UIKeyState_NotPressed)
     393//     }
     394//     else
     395//     {
     396//         pEvent->accept();
     397//     }
     398
     399// }
     400
     401void UISoftKeyboardKey::updateState(bool fPressed)
     402{
     403    if (m_enmType == UIKeyType_TriState)
     404    {
     405        if (fPressed)
     406        {
     407            if (m_enmState == UIKeyState_NotPressed)
     408                m_enmState = UIKeyState_Pressed;
     409            else if(m_enmState == UIKeyState_Pressed)
     410                m_enmState = UIKeyState_Locked;
     411            else
     412                m_enmState = UIKeyState_NotPressed;
     413        }
     414        else
     415        {
     416            if(m_enmState == UIKeyState_Pressed)
     417                m_enmState = UIKeyState_NotPressed;
     418        }
     419    }
     420    else if (m_enmType == UIKeyType_DualState)
     421    {
     422        if (fPressed)
     423        {
     424            if (m_enmState == UIKeyState_NotPressed)
     425                 m_enmState = UIKeyState_Pressed;
     426            else
     427                m_enmState = UIKeyState_NotPressed;
     428        }
     429    }
     430    emit sigStateChanged();
     431    updateBackground();
     432}
     433
     434 void UISoftKeyboardKey::updateBackground()
     435 {
     436     if (m_enmState == UIKeyState_NotPressed)
     437     {
     438         setPalette(m_defaultPalette);
     439         return;
     440     }
     441     QColor newColor;
     442
     443     if (m_enmState == UIKeyState_Pressed)
     444         newColor = QColor(255, 0, 0);
     445     else
     446         newColor = QColor(0, 255, 0);
     447
     448     setAutoFillBackground(true);
     449     QPalette currentPalette = palette();
     450     currentPalette.setColor(QPalette::Button, newColor);
     451     currentPalette.setColor(QPalette::ButtonText, newColor);
     452     setPalette(currentPalette);
     453     update();
     454 }
     455
     456 /*********************************************************************************************************************************
     457  *   UISoftKeyboardRow implementation.                                                                                  *
    269458*********************************************************************************************************************************/
    270459
     
    299488        }
    300489        iX += fMultiplier * pKey->width();
     490        iX += fMultiplier * pKey->spaceAfter();
    301491    }
    302492}
     
    347537    if (!pKey)
    348538        return;
     539    if (pKey->type() != UIKeyType_SingleState)
     540        return;
     541
    349542    QVector<LONG> sequence;
     543
     544    /* Add the pressed modifiers first: */
     545    for (int i = 0; i < m_pressedModifiers.size(); ++i)
     546    {
     547        UISoftKeyboardKey *pModifier = m_pressedModifiers[i];
     548        if (pModifier->scanCodePrefix() != 0)
     549            sequence << pModifier->scanCodePrefix();
     550        sequence << pModifier->scanCode();
     551    }
     552
    350553    if (pKey->scanCodePrefix() != 0)
    351554        sequence << pKey->scanCodePrefix();
    352555    sequence << pKey->scanCode();
    353556    keyboard().PutScancodes(sequence);
    354     printf("sending for press: ");
    355     for (int i = 0; i < sequence.size(); ++i)
    356         printf("%#04x ", sequence[i]);
    357     printf("\n");
    358557}
    359558
     
    362561    UISoftKeyboardKey *pKey = qobject_cast<UISoftKeyboardKey*>(sender());
    363562    if (!pKey)
     563        return;
     564
     565    if (pKey->type() != UIKeyType_SingleState)
    364566        return;
    365567
     
    368570        sequence <<  pKey->scanCodePrefix();
    369571    sequence << (pKey->scanCode() | 0x80);
     572
     573    /* Add the pressed modifiers in the reverse order: */
     574    for (int i = m_pressedModifiers.size() - 1; i >= 0; --i)
     575    {
     576        UISoftKeyboardKey *pModifier = m_pressedModifiers[i];
     577        if (pModifier->scanCodePrefix() != 0)
     578            sequence << pModifier->scanCodePrefix();
     579        sequence << (pModifier->scanCode() | 0x80);
     580        /* Release the pressed modifiers (if there are not locked): */
     581        pModifier->release();
     582    }
    370583    keyboard().PutScancodes(sequence);
    371     printf("sending for release: ");
    372     for (int i = 0; i < sequence.size(); ++i)
    373         printf("%#04x ", sequence[i]);
    374     printf("\n");
     584}
     585
     586void UISoftKeyboard::sltHandleModifierStateChange()
     587{
     588    UISoftKeyboardKey *pKey = qobject_cast<UISoftKeyboardKey*>(sender());
     589    if (!pKey)
     590        return;
     591    if (pKey->type() == UIKeyType_SingleState)
     592        return;
     593    if (pKey->state() == UIKeyState_NotPressed)
     594    {
     595        m_pressedModifiers.removeOne(pKey);
     596    }
     597    else
     598    {
     599        if (!m_pressedModifiers.contains(pKey))
     600            m_pressedModifiers.append(pKey);
     601    }
    375602}
    376603
     
    427654        for (int j = 0; j < layout.m_rows[i].m_keys.size(); ++j)
    428655        {
    429             pNewRow->m_iWidth += layout.m_rows[i].m_keys[j].m_iWidth;
     656            const SoftKeyboardKey &key = layout.m_rows[i].m_keys[j];
     657            pNewRow->m_iWidth += key.m_iWidth;
     658            pNewRow->m_iWidth += key.m_iSpaceAfter;
    430659            UISoftKeyboardKey *pKey = new UISoftKeyboardKey(pNewRow);
    431660            if (!pKey)
     
    433662            connect(pKey, &UISoftKeyboardKey::pressed, this, &UISoftKeyboard::sltHandleKeyPress);
    434663            connect(pKey, &UISoftKeyboardKey::released, this, &UISoftKeyboard::sltHandleKeyRelease);
     664            connect(pKey, &UISoftKeyboardKey::sigStateChanged, this, &UISoftKeyboard::sltHandleModifierStateChange);
    435665            pNewRow->m_keys.append(pKey);
    436             pKey->setText(layout.m_rows[i].m_keys[j].m_strLabel);
    437             pKey->setWidth(layout.m_rows[i].m_keys[j].m_iWidth);
    438             pKey->setScanCode(layout.m_rows[i].m_keys[j].m_scanCode);
    439             pKey->setScanCodePrefix(layout.m_rows[i].m_keys[j].m_scanCodePrefix);
     666            pKey->setText(key.m_strLabel);
     667            pKey->setWidth(key.m_iWidth);
     668            pKey->setScanCode(key.m_scanCode);
     669            pKey->setScanCodePrefix(key.m_scanCodePrefix);
     670            pKey->setSpaceAfter(key.m_iSpaceAfter);
     671            pKey->setType(key.m_enmType);
    440672            pKey->hide();
    441673        }
    442         printf("row width %d %d\n", i, pNewRow->m_iWidth);
    443674        m_iMaxRowWidth = qMax(m_iMaxRowWidth, pNewRow->m_iWidth);
    444675    }
  • trunk/src/VBox/Frontends/VirtualBox/src/softkeyboard/UISoftKeyboard.h

    r78635 r78661  
    6262    void sltHandleKeyPress();
    6363    void sltHandleKeyRelease();
     64    void sltHandleModifierStateChange();
    6465
    6566private:
     
    8384    int           m_iTotalRowHeight;
    8485    int           m_iMaxRowWidth;
     86    QVector<UISoftKeyboardKey*> m_pressedModifiers;
    8587};
    8688
  • trunk/src/VBox/Frontends/VirtualBox/xml/us_layout.xml

    r78635 r78661  
    99            <scancode>0x01</scancode>
    1010        </key>
     11        <space>
     12            <width>20</width>
     13        </space>
    1114        <key>
    1215            <width>50</width>
     
    2730            <scancode>0x3d</scancode>
    2831        </key>
     32        <space>
     33            <width>20</width>
     34        </space>
    2935        <key>
    3036            <width>50</width>
     
    4551            <scancode>0x40</scancode>
    4652        </key>
     53        <space>
     54            <width>20</width>
     55        </space>
    4756        <key>
    4857            <width>50</width>
     
    6372            <scancode>0x43</scancode>
    6473        </key>
     74        <space>
     75            <width>20</width>
     76        </space>
    6577        <key>
    6678            <width>50</width>
     
    278290            <width>70</width>
    279291            <label>CapsLock</label>
     292            <type>dualstate</type>
    280293            <position>30</position>
    281294            <scancode>0x3a</scancode>
     
    361374            <width>115</width>
    362375            <label>Shift</label>
     376            <type>tristate</type>
    363377            <position>44</position>
    364378            <scancode>0x2a</scancode>
     
    430444            <width>115</width>
    431445            <label>Shift</label>
     446            <type>tristate</type>
    432447            <position>57</position>
    433448            <scancode>0x36</scancode>
     
    440455            <width>90</width>
    441456            <label>Ctrl</label>
     457            <type>tristate</type>
    442458            <position>58</position>
    443459            <scancode>0x1d</scancode>
     
    453469            <position>60</position>
    454470            <label>Alt</label>
     471            <type>tristate</type>
    455472            <scancode>0x38</scancode>
    456473        </key>
     
    463480            <width>70</width>
    464481            <label>AltGr</label>
     482            <type>tristate</type>
    465483            <scancodeprefix>0xe0</scancodeprefix>
    466484            <scancode>0x38</scancode>
     
    481499            <width>90</width>
    482500            <label>Ctrl</label>
     501            <type>tristate</type>
    483502            <scancodeprefix>0xe0</scancodeprefix>
    484503            <scancode>0x1d</scancode>
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette