diff --git a/btgui/Gwen/Controls/Base.cpp b/btgui/Gwen/Controls/Base.cpp index dd71a4139..ba856fb91 100644 --- a/btgui/Gwen/Controls/Base.cpp +++ b/btgui/Gwen/Controls/Base.cpp @@ -81,8 +81,10 @@ Base::~Base() SetParent( NULL ); - if ( Gwen::HoveredControl == this ) Gwen::HoveredControl = NULL; - if ( Gwen::KeyboardFocus == this ) Gwen::KeyboardFocus = NULL; + if ( Gwen::HoveredControl == this ) + Gwen::HoveredControl = NULL; + if ( Gwen::KeyboardFocus == this ) + Gwen::KeyboardFocus = NULL; if ( Gwen::MouseFocus == this ) Gwen::MouseFocus = NULL; DragAndDrop::ControlDeleted( this ); diff --git a/btgui/Gwen/Controls/ComboBox.cpp b/btgui/Gwen/Controls/ComboBox.cpp index 0b08af05b..447a595d6 100644 --- a/btgui/Gwen/Controls/ComboBox.cpp +++ b/btgui/Gwen/Controls/ComboBox.cpp @@ -176,11 +176,13 @@ bool ComboBox::OnKeyUp( bool bDown ) { if ( bDown ) { - Base::List::reverse_iterator it = std::find( m_Menu->Children.rbegin(), m_Menu->Children.rend(), m_SelectedItem ); - if ( it != m_Menu->Children.rend() && ( ++it != m_Menu->Children.rend() ) ) + Base::List & children = m_Menu->GetChildren(); + Base::List::reverse_iterator it = std::find( children.rbegin(), children.rend(), m_SelectedItem ); + + if ( it != children.rend() && ( ++it != children.rend() ) ) { Base* pUpElement = *it; - OnItemSelected(pUpElement); + OnItemSelected( pUpElement ); } } return true; @@ -189,11 +191,13 @@ bool ComboBox::OnKeyDown( bool bDown ) { if ( bDown ) { - Base::List::iterator it = std::find( m_Menu->Children.begin(), m_Menu->Children.end(), m_SelectedItem ); - if ( it != m_Menu->Children.end() && ( ++it != m_Menu->Children.end() ) ) + Base::List & children = m_Menu->GetChildren(); + Base::List::iterator it = std::find( children.begin(), children.end(), m_SelectedItem ); + + if ( it != children.end() && ( ++it != children.end() ) ) { Base* pDownElement = *it; - OnItemSelected(pDownElement); + OnItemSelected( pDownElement ); } } return true; diff --git a/btgui/Gwen/Controls/ScrollControl.h b/btgui/Gwen/Controls/ScrollControl.h index a0ea68b37..187f8a49f 100644 --- a/btgui/Gwen/Controls/ScrollControl.h +++ b/btgui/Gwen/Controls/ScrollControl.h @@ -61,6 +61,7 @@ namespace Gwen bool m_bAutoHideBars; + public: Controls::BaseScrollBar* m_VerticalScrollBar; Controls::BaseScrollBar* m_HorizontalScrollBar; }; diff --git a/btgui/Gwen/Controls/TreeControl.cpp b/btgui/Gwen/Controls/TreeControl.cpp index 4c4b89d41..0a4fb123f 100644 --- a/btgui/Gwen/Controls/TreeControl.cpp +++ b/btgui/Gwen/Controls/TreeControl.cpp @@ -71,4 +71,109 @@ void TreeControl::OnNodeSelection( Controls::Base* /*control*/ ) { if ( !m_bAllowMultipleSelection || !Gwen::Input::IsKeyDown( Key::Control ) ) DeselectAll(); -} \ No newline at end of file +} + + +void TreeControl::iterate(int action, int* curIndex, int* targetIndex) +{ + + Base::List& children = m_InnerPanel->GetChildren(); + for ( Base::List::iterator iter = children.begin(); iter != children.end(); ++iter ) + { + TreeNode* pChild = (*iter)->DynamicCastTreeNode(); + if ( !pChild ) + continue; + pChild->iterate(action ,curIndex, targetIndex); + } + +} + + +bool TreeControl::OnKeyUp( bool bDown ) +{ + if (bDown) + { + int maxIndex = 0; + int newIndex = 0; + int curIndex=0; + int targetIndex=-1; + iterate(ITERATE_ACTION_FIND_SELECTED_INDEX,&curIndex,&targetIndex); + maxIndex = curIndex; + if (targetIndex>0) + { + curIndex=0; + int deselectIndex = targetIndex; + targetIndex--; + newIndex = targetIndex; + iterate(ITERATE_ACTION_SELECT,&curIndex,&targetIndex); + if (targetIndex<0) + { + curIndex=0; + iterate(ITERATE_ACTION_DESELECT_INDEX,&curIndex,&deselectIndex); + } + float amount = float(newIndex)/float(maxIndex); + m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(amount,true); + } + } + return true; +} + + +bool TreeControl::OnKeyDown( bool bDown ) +{ + if (bDown) + { + int maxIndex = 0; + int newIndex = 0; + int curIndex=0; + int targetIndex=-1; + iterate(ITERATE_ACTION_FIND_SELECTED_INDEX,&curIndex,&targetIndex); + maxIndex = curIndex; + if (targetIndex>=0) + { + curIndex=0; + int deselectIndex = targetIndex; + targetIndex++; + newIndex = targetIndex; + iterate(ITERATE_ACTION_SELECT,&curIndex,&targetIndex); + if (targetIndex<0) + { + curIndex=0; + iterate(ITERATE_ACTION_DESELECT_INDEX,&curIndex,&deselectIndex); + } + float amount = float(newIndex)/float(maxIndex); + m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(amount,true); + } + } + return true; +} + + +bool TreeControl::OnKeyRight( bool bDown ) +{ + if (bDown) + { + iterate(ITERATE_ACTION_OPEN,0,0); + int curIndex=0; + int targetIndex=0; + iterate(ITERATE_ACTION_FIND_SELECTED_INDEX,&curIndex,&targetIndex); + float amount = float(targetIndex)/float(curIndex); + m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(amount,true); + } + return true; +} +bool TreeControl::OnKeyLeft( bool bDown ) +{ + if (bDown) + { + iterate(ITERATE_ACTION_CLOSE,0,0); + + int curIndex=0; + int targetIndex=0; + iterate(ITERATE_ACTION_FIND_SELECTED_INDEX,&curIndex,&targetIndex); + float amount = float(targetIndex)/float(curIndex); + m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(amount,true); + + } + return true; +} diff --git a/btgui/Gwen/Controls/TreeControl.h b/btgui/Gwen/Controls/TreeControl.h index b165fba7c..7ab963185 100644 --- a/btgui/Gwen/Controls/TreeControl.h +++ b/btgui/Gwen/Controls/TreeControl.h @@ -36,6 +36,15 @@ namespace Gwen virtual void OnNodeAdded( TreeNode* pNode ); + virtual bool OnKeyUp( bool bDown ); + virtual bool OnKeyDown( bool bDown ); + virtual bool OnKeyRight( bool bDown ); + virtual bool OnKeyLeft( bool bDown ); + + virtual void iterate(int action,int* curIndex, int* resultIndex); + + + private: void OnNodeSelection( Controls::Base* control ); diff --git a/btgui/Gwen/Controls/TreeNode.cpp b/btgui/Gwen/Controls/TreeNode.cpp index bcf5869fd..732ef037d 100644 --- a/btgui/Gwen/Controls/TreeNode.cpp +++ b/btgui/Gwen/Controls/TreeNode.cpp @@ -208,4 +208,124 @@ void TreeNode::DeselectAll() pChild->DeselectAll( ); } +} + + +void TreeNode::iterate(int action, int* curIndex, int* targetIndex) +{ + + Gwen::String name = Gwen::Utility::UnicodeToString(m_Title->GetText()); + + int actualIndex = curIndex? *curIndex : -1; + //printf("iterated over item %d with name = %s\n", actualIndex, name.c_str()); + + if (action==ITERATE_ACTION_SELECT) + { + if (curIndex && targetIndex) + { + if ((*curIndex)==(*targetIndex)) + { + SetSelected(true); + + *targetIndex=-1; + } + } + } + + if (IsSelected()) + { + //printf("current selected: name = %s\n", name.c_str()); + switch (action) + { + case ITERATE_ACTION_DESELECT_INDEX: + { + if (targetIndex && curIndex) + { + if (*targetIndex == *curIndex) + SetSelected(false); + } + break; + } + case ITERATE_ACTION_FIND_SELECTED_INDEX: + { + if (targetIndex && curIndex) + { + *targetIndex = *curIndex; + } + break; + } + case ITERATE_ACTION_OPEN: + { + Open(); + + break; + } + case ITERATE_ACTION_CLOSE: + { + //either close or select parent + if (this->GetChildren().size()) + { + if (m_ToggleButton && m_ToggleButton->GetToggleState()) + { + Close(); + } else + { + + TreeNode* pChild = (GetParent())->DynamicCastTreeNode(); + TreeControl* pChild2 = (GetParent())->DynamicCastTreeControl(); + if (pChild && !pChild2) + { + SetSelected(false); + pChild->SetSelected(true); + } + } + } + else + { + + TreeNode* pChild = (GetParent())->DynamicCastTreeNode(); + TreeControl* pChild2 = (GetParent())->DynamicCastTreeControl(); + if (pChild && !pChild2) + { + SetSelected(false); + pChild->SetSelected(true); + } + } + + break; + } + default: + { + } + }; + } + + if (curIndex) + (*curIndex)++; + + bool needsRecursion = true; + + if (action == ITERATE_ACTION_FIND_SELECTED_INDEX || action==ITERATE_ACTION_SELECT || action==ITERATE_ACTION_DESELECT_INDEX) + { + if (m_ToggleButton && !m_ToggleButton->GetToggleState()) + { + needsRecursion=false; + } + } + + if (needsRecursion) + { + Base::List& children = m_InnerPanel->GetChildren(); + for ( Base::List::iterator iter = children.begin(); iter != children.end(); ++iter ) + { + TreeNode* pChild = (*iter)->DynamicCastTreeNode(); + if ( !pChild ) + continue; + + pChild->iterate(action , curIndex, targetIndex); + } + } + + + } \ No newline at end of file diff --git a/btgui/Gwen/Controls/TreeNode.h b/btgui/Gwen/Controls/TreeNode.h index a3cef43b5..6355a8724 100644 --- a/btgui/Gwen/Controls/TreeNode.h +++ b/btgui/Gwen/Controls/TreeNode.h @@ -12,6 +12,14 @@ #include "Gwen/Controls/Button.h" #include "Gwen/Controls/ScrollControl.h" +enum +{ + ITERATE_ACTION_OPEN=1, + ITERATE_ACTION_CLOSE, + ITERATE_ACTION_FIND_SELECTED_INDEX, + ITERATE_ACTION_DESELECT_INDEX, + ITERATE_ACTION_SELECT, +}; namespace Gwen { @@ -51,6 +59,9 @@ namespace Gwen virtual void DeselectAll(); + virtual void iterate(int action, int* curIndex, int* resultIndex); + + Event::Caller onNamePress; Event::Caller onSelectChange; Event::Caller onSelect; diff --git a/btgui/Gwen/inputhandler.cpp b/btgui/Gwen/inputhandler.cpp index 5cae979a0..43b09d415 100644 --- a/btgui/Gwen/inputhandler.cpp +++ b/btgui/Gwen/inputhandler.cpp @@ -125,8 +125,14 @@ void Gwen::Input::OnCanvasThink( Controls::Base* pControl ) if ( Gwen::MouseFocus && !Gwen::MouseFocus->Visible() ) Gwen::MouseFocus = NULL; - if ( Gwen::KeyboardFocus && ( !Gwen::KeyboardFocus->Visible() || !KeyboardFocus->GetKeyboardInputEnabled() ) ) - Gwen::KeyboardFocus = NULL; + if (Gwen::KeyboardFocus ) + { + bool isVisible = Gwen::KeyboardFocus->Visible(); + bool isEnabled = KeyboardFocus->GetKeyboardInputEnabled(); + + if ( !isVisible || !isEnabled ) + Gwen::KeyboardFocus = NULL; + } if ( !KeyboardFocus ) return; if ( KeyboardFocus->GetCanvas() != pControl ) return; diff --git a/btgui/GwenOpenGLTest/ComboBox.cpp b/btgui/GwenOpenGLTest/ComboBox.cpp index e4473c3a4..3ae13cb09 100644 --- a/btgui/GwenOpenGLTest/ComboBox.cpp +++ b/btgui/GwenOpenGLTest/ComboBox.cpp @@ -12,6 +12,7 @@ class ComboBox : public GUnit { Gwen::Controls::ComboBox* combo = new Gwen::Controls::ComboBox( this ); + combo->SetKeyboardInputEnabled(true); combo->SetPos( 50, 50 ); combo->SetWidth( 200 ); diff --git a/btgui/GwenOpenGLTest/OpenGLSample.cpp b/btgui/GwenOpenGLTest/OpenGLSample.cpp index 1289ec995..218a50d22 100644 --- a/btgui/GwenOpenGLTest/OpenGLSample.cpp +++ b/btgui/GwenOpenGLTest/OpenGLSample.cpp @@ -214,12 +214,95 @@ sth_stash* initFont(GLPrimitiveRenderer* primRenderer) return stash; } +void keyCallback(int key, int value) +{ + printf("key = %d, value = %d\n", key,value); + //pCanvas->InputKey(key,value==1); + + + int gwenKey = -1; + + switch (key) + { + case B3G_LEFT_ARROW: + { + gwenKey = Gwen::Key::Left; + break; + } + case B3G_RIGHT_ARROW: + { + gwenKey = Gwen::Key::Right; + break; + } + case B3G_UP_ARROW: + { + gwenKey = Gwen::Key::Up; + break; + } + case B3G_DOWN_ARROW: + { + gwenKey = Gwen::Key::Down; + break; + } + case B3G_BACKSPACE: + { + gwenKey = Gwen::Key::Backspace; + break; + } + case B3G_DELETE: + { + gwenKey = Gwen::Key::Delete; + break; + } + case B3G_HOME: + { + gwenKey = Gwen::Key::Home; + break; + } + case B3G_END: + { + gwenKey = Gwen::Key::End; + break; + } + case B3G_SHIFT: + { + gwenKey = Gwen::Key::Shift; + break; + } + case B3G_CONTROL: + { + gwenKey = Gwen::Key::Control; + break; + } + + + + default: + { + + } + }; + + if (gwenKey>=0) + { + pCanvas->InputKey(gwenKey,value==1); + } else + { + if (key<256 && value) + { + Gwen::UnicodeChar c = ( Gwen::UnicodeChar ) key; + pCanvas->InputCharacter(c); + } + } +} + int main() { float retinaScale = 1.f; b3gDefaultOpenGLWindow* window = new b3gDefaultOpenGLWindow(); + window->setKeyboardCallback(keyCallback); b3gWindowConstructionInfo wci; wci.m_width = sWidth; wci.m_height = sHeight; @@ -241,6 +324,7 @@ int main() gwenRenderer = new GwenOpenGL3CoreRenderer(primRenderer,font,sWidth,sHeight,retinaScale); + // // Create a GWEN OpenGL Renderer // diff --git a/btgui/GwenOpenGLTest/TreeControl.cpp b/btgui/GwenOpenGLTest/TreeControl.cpp index 9892c98df..87924ce7e 100644 --- a/btgui/GwenOpenGLTest/TreeControl.cpp +++ b/btgui/GwenOpenGLTest/TreeControl.cpp @@ -15,12 +15,17 @@ class TreeControl2 : public GUnit { Gwen::Controls::TreeControl* ctrl = new Gwen::Controls::TreeControl( this ); + ctrl->SetKeyboardInputEnabled(true); ctrl->AddNode( L"Node One" ); Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); pNode->AddNode( L"Node Two Inside" ); pNode->AddNode( L"Eyes" ); + pNode->SetSelected(true); + pNode->AddNode( L"Brown" )->AddNode( L"Node Two Inside" )->AddNode( L"Eyes" )->AddNode( L"Brown" ); ctrl->AddNode( L"Node Three" ); + ctrl->Focus(); + ctrl->SetKeyboardInputEnabled(true); ctrl->SetBounds( 30, 30, 200, 200 ); ctrl->ExpandAll(); diff --git a/btgui/GwenOpenGLTest/UnitTest.cpp b/btgui/GwenOpenGLTest/UnitTest.cpp index 97d23992d..f2f0b0741 100644 --- a/btgui/GwenOpenGLTest/UnitTest.cpp +++ b/btgui/GwenOpenGLTest/UnitTest.cpp @@ -6,6 +6,7 @@ #include "UnitTest.h" #include "Gwen/Platform.h" +#include "Gwen/Controls/TreeControl.h" using namespace Gwen; @@ -29,8 +30,81 @@ GWEN_CONTROL_CONSTRUCTOR( UnitTest ) //ADD_UNIT_TEST( MenuStrip ); + + Gwen::UnicodeString str1(L"testje"); + Gwen::Controls::TabButton* tab = m_TabControl->AddPage(str1); + + Gwen::Controls::TreeControl* ctrl=0; - ADD_UNIT_TEST( TreeControl2 ); + { + ctrl = new Gwen::Controls::TreeControl(tab->GetPage()); + + ctrl->SetKeyboardInputEnabled(true); + ctrl->AddNode( L"Node One" ); + { + Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); + pNode->AddNode( L"Node Two Inside" ); + pNode->AddNode( L"Eyes" ); + + } + { + Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); + pNode->AddNode( L"Node Two Inside" ); + pNode->AddNode( L"Eyes" ); + + } + { + Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); + pNode->AddNode( L"Node Two Inside" ); + pNode->AddNode( L"Eyes" ); + + } + { + Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); + pNode->AddNode( L"Node Two Inside" ); + pNode->AddNode( L"Eyes" ); + + } + { + Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); + pNode->AddNode( L"Node Two Inside" ); + pNode->AddNode( L"Eyes" ); + + } + { + Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); + pNode->AddNode( L"Node Two Inside" ); + pNode->AddNode( L"Eyes" ); + pNode->SetSelected(true); + + + pNode->AddNode( L"Brown" )->AddNode( L"Node Two Inside" )->AddNode( L"Eyes" )->AddNode( L"Brown" ); + } + ctrl->AddNode( L"Node Three" ); + ctrl->Focus(); + ctrl->SetKeyboardInputEnabled(true); + + ctrl->SetBounds( 30, 30, 200, 200 ); + ctrl->ExpandAll(); + + + } + + + //GUnit* u = new TreeControl2(m_TabControl);..Gwen::Controls::TreeControl2( m_TabControl ); + //GUnit* RegisterUnitTest_TreeControl2( Gwen::Controls::TabControl* tab );\ + //RegisterUnitTest_TreeControl2( m_TabControl )->SetUnitTest( this ); + + + //#define DEFINE_UNIT_TEST( name, displayname ) + //GUnit* RegisterUnitTest_TreeControl2( Gwen::Controls::TabControl* tab ) + //{ + // GUnit* u = new TreeControl2( tab ); + // tab->AddPage( displayname, u ); + // return u; + //} + + //ADD_UNIT_TEST( TreeControl2 ); ADD_UNIT_TEST( Properties2 ); @@ -59,6 +133,7 @@ GWEN_CONTROL_CONSTRUCTOR( UnitTest ) ADD_UNIT_TEST( StatusBar ); + ctrl->Focus(); PrintText( L"Unit Test Started.\n" ); m_fLastSecond = Gwen::Platform::GetTimeInSeconds(); diff --git a/btgui/OpenGLWindow/Win32Window.cpp b/btgui/OpenGLWindow/Win32Window.cpp index c3c9ca223..78b88d352 100644 --- a/btgui/OpenGLWindow/Win32Window.cpp +++ b/btgui/OpenGLWindow/Win32Window.cpp @@ -68,12 +68,13 @@ int getAsciiCodeFromVirtualKeycode(int virtualKeyCode) case VK_F9: {keycode = B3G_F9; break;} case VK_F10: {keycode= B3G_F10; break;} - case VK_SPACE: {keycode= ' '; break;} + //case VK_SPACE: {keycode= ' '; break;} case VK_NEXT: {keycode= B3G_PAGE_DOWN; break;} case VK_PRIOR: {keycode= B3G_PAGE_UP; break;} case VK_INSERT: {keycode= B3G_INSERT; break;} + case VK_BACK: {keycode= B3G_BACKSPACE; break;} case VK_DELETE: {keycode= B3G_DELETE; break;} case VK_END:{keycode= B3G_END; break;} @@ -82,9 +83,11 @@ int getAsciiCodeFromVirtualKeycode(int virtualKeyCode) case VK_UP:{keycode= B3G_UP_ARROW; break;} case VK_RIGHT:{keycode= B3G_RIGHT_ARROW; break;} case VK_DOWN:{keycode= B3G_DOWN_ARROW; break;} + case VK_SHIFT:{keycode=B3G_SHIFT;break;} + case VK_CONTROL:{keycode=B3G_CONTROL;break;} default: { - keycode = MapVirtualKey( virtualKeyCode, MAPVK_VK_TO_CHAR ) & 0x0000FFFF; + //keycode = MapVirtualKey( virtualKeyCode, MAPVK_VK_TO_CHAR ) & 0x0000FFFF; } }; @@ -127,22 +130,34 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) int keycode = getAsciiCodeFromVirtualKeycode(wParam); - if (sData && sData->m_keyboardCallback ) + if (keycode>=0 && sData && sData->m_keyboardCallback ) { int state=0; (*sData->m_keyboardCallback)(keycode,state); } return 0; } + case WM_CHAR: + { + int keycode = wParam; + + if (sData && sData->m_keyboardCallback && ((HIWORD(lParam) & KF_REPEAT) == 0)) + { + int state = 1; + (*sData->m_keyboardCallback)(keycode,state); + } + return 0; + } case WM_SYSKEYDOWN: case WM_KEYDOWN: { int keycode = getAsciiCodeFromVirtualKeycode(wParam); - if (sData && sData->m_keyboardCallback && ((HIWORD(lParam) & KF_REPEAT) == 0)) + if (keycode>=0 && sData && sData->m_keyboardCallback && ((HIWORD(lParam) & KF_REPEAT) == 0)) { int state = 1; (*sData->m_keyboardCallback)(keycode,state); + return 1; } return 0; } diff --git a/btgui/OpenGLWindow/b3gWindowInterface.h b/btgui/OpenGLWindow/b3gWindowInterface.h index 3402c8168..b8bf6dbad 100644 --- a/btgui/OpenGLWindow/b3gWindowInterface.h +++ b/btgui/OpenGLWindow/b3gWindowInterface.h @@ -35,7 +35,10 @@ enum { B3G_END, B3G_HOME, B3G_INSERT, - B3G_DELETE + B3G_DELETE, + B3G_BACKSPACE, + B3G_SHIFT, + B3G_CONTROL }; struct b3gWindowConstructionInfo