void WgMenubar::_onEvent( const WgEventPtr& pEvent, WgEventHandler * pHandler ) { WgWidget::_onEvent(pEvent,pHandler); switch( pEvent->Type() ) { case WG_EVENT_MOUSE_MOVE: case WG_EVENT_MOUSE_PRESS: { WgCoord pos = pEvent->PointerPos(); Uint32 item = _getItemAtAbsPos( pos.x, pos.y ); if( item && !m_items.Get(item-1)->m_bEnabled ) item = 0; // Item is disabled and can't be marked. if(m_markedItem != item) { m_markedItem = item; _requestRender(); } // If a menu entry already is selected we should // switch to the new marked one. if( m_selectedItem ) { if( m_markedItem && m_selectedItem != m_markedItem ) { _closeMenu( m_selectedItem ); _openMenu( m_markedItem ); } } // If this was a press, we need to select the item and open the menu. //TODO: A click on an already open entry should close the menu. if( item && pEvent->Type()== WG_EVENT_MOUSE_PRESS ) { _openMenu( item ); } } case WG_EVENT_MOUSE_LEAVE: m_markedItem = 0; _requestRender(); break; } }
void WgRefreshButton::_onEvent( const WgEventPtr& pEvent, WgEventHandler * pHandler ) { switch( pEvent->Type() ) { case WG_EVENT_TICK: { if( m_bRefreshing && m_pRefreshAnim ) { if( m_refreshMode != PROGRESS ) { WgTickEventPtr pTick = WgTickEvent::Cast(pEvent); WgGfxFrame * pOldFrame = m_pRefreshAnim->GetFrame( m_animTimer ); m_animTimer += pTick->Millisec(); WgGfxFrame * pNewFrame = m_pRefreshAnim->GetFrame( m_animTimer ); // RequestRender if animation has moved. if( pOldFrame != pNewFrame ) _requestRender(); // Check if animation has ended. if( m_bStopping && pNewFrame == m_pRefreshAnim->GetLastFrame() ) //UGLY! Change when we have updated WgAnim! { m_bRefreshing = false; m_bStopping = false; _stopReceiveTicks(); _requestRender(); } } } break; } case WG_EVENT_KEY_RELEASE: { WgKeyReleaseEventPtr pKeyRelease = WgKeyReleaseEvent::Cast(pEvent); if( m_bAutoRefresh && pKeyRelease->TranslatedKeyCode() == WG_KEY_RETURN ) StartRefresh(); break; } case WG_EVENT_MOUSE_RELEASE: { WgMouseReleaseEventPtr pBtnRelease = WgMouseReleaseEvent::Cast(pEvent); if( m_bAutoRefresh && m_bPressed && pBtnRelease->Button() == WG_BUTTON_LEFT ) StartRefresh(); break; } default: break; } WgButton::_onEvent( pEvent, pHandler ); }
void WgTablist::_onEvent( const WgEventPtr& _pEvent, WgEventHandler * pHandler ) { WgWidget::_onEvent(_pEvent,pHandler); switch( _pEvent->Type() ) { case WG_EVENT_TICK: { WgTickEventPtr pEvent = WgTickEvent::Cast(_pEvent); m_alertModeCnt -= pEvent->Millisec(); if( m_alertModeCnt <= 0 ) { m_bAlertOn = !m_bAlertOn; m_alertModeCnt = m_alertRate; // This is right, we want it to stay in the new mode at least one frame. // Check if we have to render something... WgTab * pTab = m_tabs.First(); while( pTab ) { if( pTab->m_bAlert && pTab->m_bVisible ) { _requestRender(); // Somewhat stupid to render all tabs though... break; } pTab = pTab->Next(); } } break; } case WG_EVENT_MOUSE_PRESS: { WgMouseButtonEventPtr pEvent = WgMouseButtonEvent::Cast(_pEvent); WgCoord pos = pEvent->PointerPos(); WgTab * pTab = _pos2Tab( pos.x, pos.y ); if( pTab && pTab != m_pTabSelected ) { if( pEvent->Button() == WG_BUTTON_LEFT ) SelectTab(pTab->m_id); pHandler->QueueEvent( new WgItemMousePressEvent(this, pTab->m_id, WgObjectPtr(), pEvent->Button()) ); } } break; case WG_EVENT_MOUSE_ENTER: case WG_EVENT_MOUSE_MOVE: { WgCoord pos = _pEvent->PointerPos(); WgTab * pTab = _pos2Tab( pos.x, pos.y ); if( pTab != m_pTabMarked ) { m_pTabMarked = pTab; _requestRender(); } } break; case WG_EVENT_MOUSE_LEAVE: if( m_pTabMarked ) { m_pTabMarked = 0; _requestRender(); } break; default: break; } // Swallow event depending on rules. if( _pEvent->IsMouseButtonEvent() && WgMouseButtonEvent::Cast(_pEvent)->Button() == WG_BUTTON_LEFT ) pHandler->SwallowEvent(_pEvent); }
void WgPopupLayer::_onEvent( const WgEventPtr& _pEvent, WgEventHandler * pHandler ) { WgLayer::_onEvent(_pEvent,pHandler); WgWidget * pOpener = 0; // Try to find an opener WgWidget * pOrigin = _pEvent->Widget(); if( pOrigin && pOrigin != this ) { WgPopupHook * pHook = m_popupHooks.First(); while( pHook && pHook->_widget() != pOrigin ) pHook = pHook->_next(); if( pHook && pHook->m_pOpener ) pOpener = pHook->m_pOpener.RawPtr(); } // First we try to forward event to opener (if any) if( pOpener ) { pHandler->ForwardEvent( _pEvent, pOpener ); return; } // Secondly we take care of event ourselves if it is addressed to one of our menus or us. switch( _pEvent->Type() ) { /* case WG_EVENT_MOUSE_POSITION: if( !m_popupHooks.IsEmpty() ) // Process only if we have at least one open menu. { WgCoord ofs = _pEvent->PointerPos(); WgWidget * p = _findWidget( ofs, WG_SEARCH_ACTION_TARGET ); if( p != this ) { while( p->Parent() != this ) p = p->Parent(); if( p != m_popupHooks. } } break; */ case WG_EVENT_MOUSE_RELEASE: case WG_EVENT_MOUSE_PRESS: { WgMouseButtonEventPtr pEvent = WgMouseButtonEvent::Cast(_pEvent); WgCoord ofs = pEvent->PointerPos(); WgWidget * p = _findWidget( ofs, WG_SEARCH_ACTION_TARGET ); if( p == this ) { CloseAllPopups(); pHandler->SwallowEvent( _pEvent ); return; } } break; case WG_EVENT_KEY_PRESS: case WG_EVENT_KEY_REPEAT: { WgKeyEventPtr pEvent = WgKeyEvent::Cast(_pEvent); if( pEvent->TranslatedKeyCode() == WG_KEY_ESCAPE ) { if( !m_popupHooks.IsEmpty() ) { ClosePopup( m_popupHooks.Last()->_widget() ); pHandler->SwallowEvent( _pEvent ); return; } } } break; } }
void WgMenu::_onEvent( const WgEventPtr& pEvent, WgEventHandler * pHandler ) { // TODO: Not handle or swallow key-events if some modifier keys are pressed. WgCoord mousePos = pEvent->PointerPos(); switch( pEvent->Type() ) { case WG_EVENT_TICK: { if( m_selectorCountdown > 0 ) { WgTickEventPtr pTick = WgTickEvent::Cast(pEvent); m_selectorCountdown -= pTick->Millisec(); if( m_selectorCountdown < 0 ) { m_selectorCountdown = 0; m_nSelectorKeys = 0; } } return; } case WG_EVENT_MOUSE_LEAVE: { // Unmark any selected item unless it is a submenu... WgMenuItem * pOldItem = m_items.Get(m_markedItem-1); if( pOldItem && pOldItem->GetType() != SUBMENU ) { m_markedItem = 0; _requestRender(); } } break; case WG_EVENT_MOUSE_ENTER: case WG_EVENT_MOUSE_MOVE: { WgMenuItem * pItem = _getItemAtPos( mousePos.x, mousePos.y ); Uint32 markedItem = 0; if( pItem ) { if( pItem->GetType() != SEPARATOR ) { if( ((WgMenuEntry*)pItem)->IsEnabled() ) markedItem = pItem->Index()+1; } } if( m_markedItem != markedItem ) { // Mark and request render m_markedItem = markedItem; _requestRender(); // Open/close submenus depending on what item we have marked. if( pItem && pItem->GetType() == SUBMENU ) { WgMenuSubMenu * pSubMenu = (WgMenuSubMenu*) pItem; if( pSubMenu != m_pOpenSubMenu ) { if( m_pOpenSubMenu ) _closeSubMenu( m_pOpenSubMenu ); _openSubMenu( pSubMenu ); } } else if( m_pOpenSubMenu ) { _closeSubMenu( m_pOpenSubMenu ); } } } break; case WG_EVENT_MOUSE_RELEASE: { WgMenuItem * pItem = _getItemAtPos( mousePos.x, mousePos.y ); if( pItem ) SelectItem(pItem); } break; case WG_EVENT_WHEEL_ROLL: { WgWheelRollEventPtr pEv = WgWheelRollEvent::Cast(pEvent); if( pEv->Wheel() == 1 ) { int distance = pEv->Distance(); _setViewOfs( m_contentOfs - m_entryHeight*distance ); _updateScrollbar( _getHandlePosition(), _getHandleSize() ); } } case WG_EVENT_CHARACTER: { Uint16 chr = WgCharacterEvent::Cast(pEvent)->Char(); if( chr != 0 ) { m_selectorCountdown = c_selectorCountdownStart; if( m_nSelectorKeys < c_maxSelectorKeys ) { m_selectorKeys[m_nSelectorKeys++] = towlower( chr ); _markFirstFilteredEntry(); } } } break; case WG_EVENT_KEY_PRESS: case WG_EVENT_KEY_REPEAT: { WgMenuItem * pItem = 0; if( m_markedItem != 0 ) pItem = m_items.Get( m_markedItem-1 ); int key = WgKeyEvent::Cast(pEvent)->TranslatedKeyCode(); switch( key ) { case WG_KEY_ESCAPE: if( m_pOpenSubMenu ) { _closeSubMenu( m_pOpenSubMenu ); } break; case WG_KEY_LEFT: if( m_pOpenSubMenu ) { _closeSubMenu( m_pOpenSubMenu ); } break; case WG_KEY_RIGHT: if( pItem ) { if( pItem->GetType() == SUBMENU ) { _openSubMenu( (WgMenuSubMenu*) pItem ); } } break; case WG_KEY_RETURN: if( pItem ) { if( pItem->GetType() == SUBMENU ) _openSubMenu( (WgMenuSubMenu*) pItem ); else { SelectItem(pItem); pItem = 0; // So we won't mark an item in the closed menu. } } break; case WG_KEY_UP: if( pItem ) { pItem = pItem->Prev(); while( pItem != 0 && (pItem->GetType() == SEPARATOR || !pItem->IsVisible() ) ) pItem = pItem->Prev(); } break; case WG_KEY_DOWN: if( pItem ) pItem = pItem->Next(); else pItem = m_items.First(); while( pItem != 0 && (pItem->GetType() == SEPARATOR || !pItem->IsVisible() ) ) pItem = pItem->Next(); break; case WG_KEY_HOME: pItem = m_items.First(); while( pItem != 0 && (pItem->GetType() == SEPARATOR || !pItem->IsVisible() ) ) pItem = pItem->Next(); break; case WG_KEY_END: pItem = m_items.Last(); while( pItem != 0 && (pItem->GetType() == SEPARATOR || !pItem->IsVisible() )) pItem = pItem->Prev(); break; case WG_KEY_PAGE_UP: { int viewHeight = _getViewSize(); int distance = m_entryHeight; while( pItem != 0 && distance < viewHeight ) { if( pItem->IsVisible() ) { if( pItem->GetType() == SEPARATOR ) distance += m_sepHeight; else distance += m_entryHeight; } pItem = pItem->Prev(); } if( !pItem ) { pItem = m_items.First(); while( pItem != 0 && (pItem->GetType() == SEPARATOR || !pItem->IsVisible() )) pItem = pItem->Next(); } break; } case WG_KEY_PAGE_DOWN: { int viewHeight = _getViewSize(); int distance = m_entryHeight; while( pItem != 0 && distance < viewHeight ) { if( pItem->IsVisible() ) { if( pItem->GetType() == SEPARATOR ) distance += m_sepHeight; else distance += m_entryHeight; } pItem = pItem->Next(); } if( !pItem ) { pItem = m_items.Last(); while( pItem != 0 && (pItem->GetType() == SEPARATOR || !pItem->IsVisible() )) pItem = pItem->Next(); } break; } } if( pItem ) { Uint32 markedItem = pItem->Index()+1; if( markedItem != m_markedItem ) { m_markedItem = markedItem; _scrollItemIntoView(pItem); _requestRender(); } } } break; default: break; } // Forward event depending on rules. if( pEvent->IsMouseButtonEvent() && WgMouseButtonEvent::Cast(pEvent)->Button() == WG_BUTTON_LEFT ) pHandler->SwallowEvent(pEvent); else if( pEvent->IsKeyEvent() ) { int key = WgKeyEvent::Cast(pEvent)->TranslatedKeyCode(); if( key == WG_KEY_RIGHT || key == WG_KEY_RETURN || key == WG_KEY_UP || key == WG_KEY_DOWN && key == WG_KEY_HOME || key == WG_KEY_END || key == WG_KEY_PAGE_UP || key == WG_KEY_PAGE_DOWN && key == WG_KEY_ESCAPE || key == WG_KEY_LEFT ) pHandler->SwallowEvent(pEvent); } else if( pEvent->Type() == WG_EVENT_CHARACTER || pEvent->Type() == WG_EVENT_WHEEL_ROLL ) pHandler->SwallowEvent(pEvent); }
void WgPackList::_onEvent( const WgEventPtr& _pEvent, WgEventHandler * pHandler ) { WgState oldState = m_state; switch( _pEvent->Type() ) { case WG_EVENT_MOUSE_MOVE: { WgMouseMoveEventPtr pEvent = WgMouseMoveEvent::Cast(_pEvent); WgCoord ofs = ToLocal(pEvent->PointerGlobalPos()); WgRect headerGeo = _headerGeo(); bool bHeaderHovered = headerGeo.Contains(ofs) && (!pHandler->IsAnyMouseButtonPressed() || (pHandler->IsMouseButtonPressed(WG_BUTTON_LEFT) && m_header.m_bPressed)); if( bHeaderHovered != m_header.m_state.IsHovered() ) { m_header.m_state.SetHovered(bHeaderHovered); _requestRender( headerGeo ); } WgList::_onEvent( _pEvent, pHandler ); break; } case WG_EVENT_MOUSE_LEAVE: { WgMouseLeaveEventPtr pEvent = WgMouseLeaveEvent::Cast(_pEvent); if( pEvent->Widget() == this && m_header.m_state.IsHovered() ) { m_header.m_state.SetPressed(false); m_header.m_state.SetHovered(false); _requestRender( _headerGeo() ); } WgList::_onEvent( _pEvent, pHandler ); break; } case WG_EVENT_MOUSE_PRESS: { WgMousePressEventPtr pEvent = WgMousePressEvent::Cast(_pEvent); WgCoord ofs = ToLocal(pEvent->PointerGlobalPos()); WgRect headerGeo = _headerGeo(); if(pEvent->Button() == WG_BUTTON_LEFT && headerGeo.Contains(ofs)) { m_header.m_bPressed = true; m_header.m_state.SetPressed(true); _requestRender( headerGeo ); pHandler->SwallowEvent( pEvent ); } else WgList::_onEvent( _pEvent, pHandler ); break; } case WG_EVENT_MOUSE_DRAG: { WgMouseDragEventPtr pEvent = WgMouseDragEvent::Cast(_pEvent); if( m_header.m_bPressed ) { WgCoord ofs = ToLocal(pEvent->PointerGlobalPos()); WgRect headerGeo = _headerGeo(); bool bHeaderHovered = headerGeo.Contains(ofs); if( bHeaderHovered != m_header.m_state.IsHovered() ) { m_header.m_state.SetHovered(bHeaderHovered); m_header.m_state.SetPressed(bHeaderHovered); _requestRender( headerGeo ); } pHandler->SwallowEvent(pEvent); } else WgList::_onEvent( _pEvent, pHandler ); break; } case WG_EVENT_MOUSE_RELEASE: { WgMouseReleaseEventPtr pEvent = WgMouseReleaseEvent::Cast(_pEvent); if(pEvent->Button() == WG_BUTTON_LEFT && m_header.m_bPressed ) { m_header.m_bPressed = false; m_header.m_state.SetPressed(false); WgRect headerGeo = _headerGeo(); _requestRender( headerGeo ); WgCoord ofs = ToLocal(pEvent->PointerGlobalPos()); if( headerGeo.Contains(ofs) ) { if( m_sortOrder == WG_SORT_ASCENDING ) m_sortOrder = WG_SORT_DESCENDING; else m_sortOrder = WG_SORT_ASCENDING; _sortEntries(); } pHandler->SwallowEvent(pEvent); } else WgList::_onEvent( _pEvent, pHandler ); break; } case WG_EVENT_KEY_PRESS: { if( m_selectMode == WG_SELECT_NONE ) break; int keyCode = WgKeyPressEvent::Cast(_pEvent)->TranslatedKeyCode(); WgModifierKeys modKeys = WgKeyPressEvent::Cast(_pEvent)->ModKeys(); if( (m_bHorizontal && (keyCode == WG_KEY_LEFT || keyCode == WG_KEY_RIGHT)) || (!m_bHorizontal && (keyCode == WG_KEY_UP || keyCode == WG_KEY_DOWN || keyCode == WG_KEY_PAGE_UP || keyCode == WG_KEY_PAGE_DOWN)) || keyCode == WG_KEY_HOME || keyCode == WG_KEY_END || (m_selectMode == WG_SELECT_FLIP && keyCode == WG_KEY_SPACE ) ) pHandler->SwallowEvent(_pEvent); WgList::_onEvent( _pEvent, pHandler ); break; } case WG_EVENT_KEY_REPEAT: case WG_EVENT_KEY_RELEASE: { if( m_selectMode == WG_SELECT_NONE ) break; int keyCode = WgKeyEvent::Cast(_pEvent)->TranslatedKeyCode(); WgModifierKeys modKeys = WgKeyEvent::Cast(_pEvent)->ModKeys(); if( (m_bHorizontal && (keyCode == WG_KEY_LEFT || keyCode == WG_KEY_RIGHT)) || (!m_bHorizontal && (keyCode == WG_KEY_UP || keyCode == WG_KEY_DOWN || keyCode == WG_KEY_PAGE_UP || keyCode == WG_KEY_PAGE_DOWN)) || keyCode == WG_KEY_HOME || keyCode == WG_KEY_END || (m_selectMode == WG_SELECT_FLIP && keyCode == WG_KEY_SPACE ) ) pHandler->SwallowEvent(_pEvent); WgList::_onEvent( _pEvent, pHandler ); break; } default: WgList::_onEvent(_pEvent, pHandler); return; } if( m_state != oldState ) _onStateChanged(oldState); }
void WgLineEditor::_onEvent( const WgEventPtr& pEvent, WgEventHandler * pHandler ) { WgWidget::_onEvent(pEvent,pHandler); WgEventType event = pEvent->Type(); if( event == WG_EVENT_TICK ) { if( _isSelectable() && m_state.IsFocused() ) { m_text.incTime( WgTickEvent::Cast(pEvent)->Millisec() ); _requestRender(); //TODO: Should only render the cursor and selection! } return; } if( (event == WG_EVENT_MOUSE_PRESS || event == WG_EVENT_MOUSE_DRAG) && WgMouseButtonEvent::Cast(pEvent)->Button() == WG_BUTTON_LEFT ) { if( !m_state.IsFocused() ) GrabFocus(); if( m_state.IsFocused() ) { if( _isSelectable() && (pEvent->ModKeys() & WG_MODKEY_SHIFT) ) { m_text.setSelectionMode(true); } WgCoord ofs = pEvent->PointerPos(); int x = ofs.x + m_viewOfs; int y = 0; if( m_bPasswordMode ) { WgTextAttr attr; m_text.GetBaseAttr( attr ); WgPen pen; pen.SetAttributes( attr ); pen.SetChar(m_pwGlyph); pen.AdvancePos(); int spacing = pen.GetPosX(); int height = pen.GetLineSpacing(); int line = y/height; int col = (x+spacing/2)/spacing; if(col < 0) { col = 0; line = 0; } m_text.gotoSoftPos(line,col); } else { m_text.CursorGotoCoord( WgCoord(x, 0), WgRect(0,0,1000000,1000000) ); } if(_isSelectable() && event == WG_EVENT_MOUSE_PRESS && !(pEvent->ModKeys() & WG_MODKEY_SHIFT)) { m_text.ClearSelection(); m_text.setSelectionMode(true); } } _adjustViewOfs(); } if( event == WG_EVENT_MOUSE_RELEASE ) { if( m_state.IsFocused() && WgMouseButtonEvent::Cast(pEvent)->Button() == WG_BUTTON_LEFT ) m_text.setSelectionMode(false); } if( event == WG_EVENT_CHARACTER ) { int ch = WgCharacterEvent::Cast(pEvent)->Char(); if( _isEditable() && m_state.IsFocused() && ch >= 32 && ch != 127) { if(m_text.hasSelection()) m_text.delSelection(); m_text.setSelectionMode(false); if( m_text.putChar( ch ) ) { if( pHandler ) pHandler->QueueEvent( new WgTextEditEvent(this,&text,false) ); _adjustViewOfs(); } } } if( event == WG_EVENT_KEY_RELEASE && m_state.IsFocused() ) { int key = WgKeyEvent::Cast(pEvent)->TranslatedKeyCode(); switch( key ) { case WG_KEY_SHIFT: if(!pHandler->IsMouseButtonPressed(1)) m_text.setSelectionMode(false); break; } } if( (event == WG_EVENT_KEY_PRESS || event == WG_EVENT_KEY_REPEAT) && _isEditable() && m_state.IsFocused() ) { int key = WgKeyEvent::Cast(pEvent)->TranslatedKeyCode(); switch( key ) { case WG_KEY_LEFT: if( pEvent->ModKeys() & WG_MODKEY_SHIFT ) m_text.setSelectionMode(true); if( pEvent->ModKeys() & WG_MODKEY_CTRL ) { if( m_bPasswordMode ) m_text.GoBOL(); else m_text.gotoPrevWord(); } else { m_text.goLeft(); } break; case WG_KEY_RIGHT: if( pEvent->ModKeys() & WG_MODKEY_SHIFT ) m_text.setSelectionMode(true); if( pEvent->ModKeys() & WG_MODKEY_CTRL ) { if( m_bPasswordMode ) m_text.GoEOL(); else m_text.gotoNextWord(); } else { m_text.goRight(); } break; case WG_KEY_BACKSPACE: { if(m_text.hasSelection()) m_text.delSelection(); else if( (pEvent->ModKeys() & WG_MODKEY_CTRL) && !m_bPasswordMode) m_text.delPrevWord(); else m_text.delPrevChar(); if( pHandler ) pHandler->QueueEvent( new WgTextEditEvent(this,&text,false) ); break; } case WG_KEY_DELETE: { if(m_text.hasSelection()) m_text.delSelection(); else if( (pEvent->ModKeys() & WG_MODKEY_CTRL) && !m_bPasswordMode) m_text.delNextWord(); else m_text.delNextChar(); if( pHandler ) pHandler->QueueEvent( new WgTextEditEvent(this,&text,false) ); break; } case WG_KEY_HOME: /* * I am not sure if this is the proper way to this, but in my opinion, the default * "actions" has to be separated from any modifier key action combination */ switch( pEvent->ModKeys() ) { case WG_MODKEY_CTRL: break; default: // no modifier key was pressed if(pEvent->ModKeys() & WG_MODKEY_SHIFT ) m_text.setSelectionMode(true); m_text.GoBOL(); break; } break; case WG_KEY_END: /* * I am not sure if this is the proper way to this, but in my opinion, the default * "actions" has to be separated from any modifier key action combination */ switch( pEvent->ModKeys() ) { case WG_MODKEY_CTRL: break; default: // no modifier key was pressed if( pEvent->ModKeys() & WG_MODKEY_SHIFT ) m_text.setSelectionMode(true); m_text.GoEOL(); break; } break; default: break; } _adjustViewOfs(); } // Forward event depending on rules. if( pEvent->IsMouseButtonEvent() ) { if( WgMouseButtonEvent::Cast(pEvent)->Button() == WG_BUTTON_LEFT ) pHandler->SwallowEvent(pEvent); } else if( pEvent->IsKeyEvent() ) { int key = WgKeyEvent::Cast(pEvent)->TranslatedKeyCode(); if( WgKeyEvent::Cast(pEvent)->IsMovementKey() == true || key == WG_KEY_DELETE || key == WG_KEY_BACKSPACE ) pHandler->SwallowEvent(pEvent); //TODO: Would be good if we didn't forward any character-creating keys either... } }