text: 
  #include "gwenUserInterface.h"
  #include "gwenInternalData.h"
  #include "Gwen/Controls/ImagePanel.h"
  
  class MyGraphWindow* graphWindow = 0;
  
  
  
  GwenUserInterface::GwenUserInterface()
  {
  	m_data = new GwenInternalData();
  	m_data->m_toggleButtonCallback = 0;
  	m_data->m_comboBoxCallback = 0;
  
  }
  
  GwenUserInterface::~GwenUserInterface()
  {
  	for (int i=0;i<m_data->m_handlers.size();i++)
  	{
  		delete m_data->m_handlers[i];
  	}
  
  	m_data->m_handlers.clear();
  
  
  	delete m_data->pCanvas;
  
  
  	delete m_data;
  
  
  
  }
  
  
  
  
  class MyMenuItems :  public Gwen::Controls::Base
  {
  public:
  
      b3FileOpenCallback m_fileOpenCallback;
      b3QuitCallback m_quitCallback;
      
      MyMenuItems() :Gwen::Controls::Base(0),m_fileOpenCallback(0)
      {
      }
      void myQuitApp( Gwen::Controls::Base* pControl )
      {
          if (m_quitCallback)
          {
              (*m_quitCallback)();
          }
      }
      void fileOpen( Gwen::Controls::Base* pControl )
      {
          if (m_fileOpenCallback)
          {
              (*m_fileOpenCallback)();
          }
      }
      
  };
  
  struct MyTestMenuBar : public Gwen::Controls::MenuStrip
  {
  
  	Gwen::Controls::MenuItem* m_fileMenu;
  	Gwen::Controls::MenuItem* m_viewMenu;
      MyMenuItems*                m_menuItems;
  
  	MyTestMenuBar(Gwen::Controls::Base* pParent)
  		:Gwen::Controls::MenuStrip(pParent)
  	{
  //		Gwen::Controls::MenuStrip* menu = new Gwen::Controls::MenuStrip( pParent );
  		{
  			m_menuItems = new MyMenuItems();
              m_menuItems->m_fileOpenCallback = 0;
              m_menuItems->m_quitCallback = 0;
              
  			m_fileMenu = AddItem( L"File" );
  			
              m_fileMenu->GetMenu()->AddItem(L"Open",m_menuItems,(Gwen::Event::Handler::Function)&MyMenuItems::fileOpen);
              m_fileMenu->GetMenu()->AddItem(L"Quit",m_menuItems,(Gwen::Event::Handler::Function)&MyMenuItems::myQuitApp);
              m_viewMenu = AddItem( L"View" );
  			
  		}
  	}
  
  };
  
  void	GwenUserInterface::resize(int width, int height)
  {
  	m_data->pCanvas->SetSize(width,height);
  }
  
  
  struct MyComboBoxHander   :public Gwen::Event::Handler
  {
  	GwenInternalData*	m_data;
  	int					m_buttonId;
  
  	MyComboBoxHander  (GwenInternalData* data, int buttonId)
  		:m_data(data),
  		m_buttonId(buttonId)
  	{
  	}
  
  	void onSelect( Gwen::Controls::Base* pControl )
  	{
  		Gwen::Controls::ComboBox* but = (Gwen::Controls::ComboBox*) pControl;
  
  
  
  		Gwen::String str = Gwen::Utility::UnicodeToString(	but->GetSelectedItem()->GetText());
  
  		if (m_data->m_comboBoxCallback)
  			(*m_data->m_comboBoxCallback)(m_buttonId,str.c_str());
  	}
  
  };
  
  struct MyButtonHander   :public Gwen::Event::Handler
  {
  	GwenInternalData*	m_data;
  	int					m_buttonId;
  
  	MyButtonHander  (GwenInternalData* data, int buttonId)
  		:m_data(data),
  		m_buttonId(buttonId)
  	{
  	}
  
  	void onButtonA( Gwen::Controls::Base* pControl )
  	{
  		Gwen::Controls::Button* but = (Gwen::Controls::Button*) pControl;
  //		int dep = but->IsDepressed();
  		int tog = but->GetToggleState();
  		if (m_data->m_toggleButtonCallback)
  			(*m_data->m_toggleButtonCallback)(m_buttonId,tog);
  	}
  
  };
  
  
  void	GwenUserInterface::textOutput(const char* message)
  {
  	Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(message);
  	m_data->m_TextOutput->AddItem( msg );
  	m_data->m_TextOutput->Scroller()->ScrollToBottom();
  }
  
  
  void	GwenUserInterface::setExampleDescription(const char* message)
  {
  	//Gwen apparently doesn't have text/word wrap, so do rudimentary brute-force implementation here.
  	
  	std::string wrapmessage=message;
  	int startPos = 0;
  	
  	std::string lastFit = "";
  	bool hasSpace = false;
  	std::string lastFitSpace = "";
  	int spacePos = 0;
  
  	m_data->m_exampleInfoTextOutput->Clear();
  	int fixedWidth = m_data->m_exampleInfoTextOutput->GetBounds().w-25;
  
  	for (int endPos=0;endPos<=wrapmessage.length();endPos++)
  	{
  		std::string sub = wrapmessage.substr(startPos,(endPos-startPos));	
  		Gwen::Point pt = m_data->pRenderer->MeasureText(m_data->pCanvas->GetSkin()->GetDefaultFont(),sub);
  		
  		if (pt.x <= fixedWidth)
  		{
  			lastFit = sub;
  
  			if (message[endPos]==' ' ||message[endPos]=='.' || message[endPos]==',' )
  			{
  				hasSpace = true;
  				lastFitSpace = sub;
  				spacePos = endPos;
  			}
  		} else
  		{
  			//submit and 
  			if (hasSpace)
  			{
  				endPos = spacePos+1;
  				hasSpace = false;
  				lastFit = lastFitSpace;
  				startPos = endPos;
  			} else
  			{
  				startPos = endPos-1;
  			}
  			Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(lastFit);
  			
  			m_data->m_exampleInfoTextOutput->AddItem( msg );
  			m_data->m_exampleInfoTextOutput->Scroller()->ScrollToBottom();
  			
  		}
  	}
  	
  	if (lastFit.length())
  	{
  		Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(lastFit);
  		m_data->m_exampleInfoTextOutput->AddItem( msg );
  		m_data->m_exampleInfoTextOutput->Scroller()->ScrollToBottom();
  	
  	}
  
  }
  
  
  
  
  void	GwenUserInterface::setStatusBarMessage(const char* message, bool isLeft)
  {
  	Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(message);
  	if (isLeft)
  	{
  		m_data->m_leftStatusBar->SetText( msg);
  	} else
  	{
  		m_data->m_rightStatusBar->SetText( msg);
  
  	}
  }
  
  void GwenUserInterface::registerFileOpenCallback(b3FileOpenCallback callback)
  {
      m_data->m_menuItems->m_fileOpenCallback = callback;
  }
  
  void GwenUserInterface::registerQuitCallback(b3QuitCallback callback)
  {
      m_data->m_menuItems->m_quitCallback = callback;
  }
  
  void	GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* renderer,float retinaScale)
  {
  	m_data->m_curYposition = 20;
  	//m_data->m_primRenderer = new GLPrimitiveRenderer(width,height);
  	m_data->pRenderer = renderer;//new GwenOpenGL3CoreRenderer(m_data->m_primRenderer,stash,width,height,retinaScale);
  
  	m_data->skin.SetRender( m_data->pRenderer );
  
  	m_data->pCanvas= new Gwen::Controls::Canvas( &m_data->skin );
  	m_data->pCanvas->SetSize( width,height);
  	m_data->pCanvas->SetDrawBackground( false);
  	m_data->pCanvas->SetBackgroundColor( Gwen::Color( 150, 170, 170, 255 ) );
  
  
  
  	MyTestMenuBar* menubar = new MyTestMenuBar(m_data->pCanvas);
  	m_data->m_viewMenu = menubar->m_viewMenu;
      m_data->m_menuItems = menubar->m_menuItems;
      
  	
      
      
  	Gwen::Controls::StatusBar* bar = new Gwen::Controls::StatusBar(m_data->pCanvas);
  	m_data->m_rightStatusBar = new Gwen::Controls::Label( bar );
  	m_data->m_rightStatusBar->SetWidth(width/2);
  	//m_data->m_rightStatusBar->SetText( L"Label Added to Right" );
  	bar->AddControl( m_data->m_rightStatusBar, true );
  
  	m_data->m_TextOutput = new Gwen::Controls::ListBox( m_data->pCanvas );
  	m_data->m_TextOutput->Dock( Gwen::Pos::Bottom );
  	m_data->m_TextOutput->SetHeight( 100 );
  
  	m_data->m_leftStatusBar = new Gwen::Controls::Label( bar );
  	//m_data->m_leftStatusBar->SetText( L"Label Added to Left" );
  	m_data->m_leftStatusBar->SetWidth(width/2);
  	bar->AddControl( m_data->m_leftStatusBar,false);
  	//Gwen::KeyboardFocus
  	/*Gwen::Controls::GroupBox* box = new Gwen::Controls::GroupBox(m_data->pCanvas);
  	box->SetText("text");
  	box->SetName("name");
  	box->SetHeight(500);
  	*/
  	Gwen::Controls::ScrollControl* windowRight= new Gwen::Controls::ScrollControl(m_data->pCanvas);
  	windowRight->Dock(Gwen::Pos::Right);
  	windowRight->SetWidth(150);
  	windowRight->SetHeight(250);
  	windowRight->SetScroll(false,true);
  
  
  
  	//windowLeft->SetSkin(
  	Gwen::Controls::TabControl* tab = new Gwen::Controls::TabControl(windowRight);
  
  	//tab->SetHeight(300);
  	tab->SetWidth(140);
  	tab->SetHeight(250);
  	//tab->Dock(Gwen::Pos::Left);
  	tab->Dock( Gwen::Pos::Fill );
  	//tab->SetMargin( Gwen::Margin( 2, 2, 2, 2 ) );
  
  	Gwen::UnicodeString str1(L"Params");
  	m_data->m_demoPage = tab->AddPage(str1);
  
  
  
  
  //	Gwen::UnicodeString str2(L"OpenCL");
  //	tab->AddPage(str2);
  	//Gwen::UnicodeString str3(L"page3");
  //	tab->AddPage(str3);
  
  
  
  	//but->onPress.Add(handler, &MyHander::onButtonA);
  
  
  
  	//box->Dock(Gwen::Pos::Left);
  
  	/*Gwen::Controls::WindowControl* windowBottom = new Gwen::Controls::WindowControl(m_data->pCanvas);
  	windowBottom->SetHeight(100);
  	windowBottom->Dock(Gwen::Pos::Bottom);
  	windowBottom->SetTitle("bottom");
  	*/
  //	Gwen::Controls::Property::Text* prop = new Gwen::Controls::Property::Text(m_data->pCanvas);
  	//prop->Dock(Gwen::Pos::Bottom);
  	/*Gwen::Controls::SplitterBar* split = new Gwen::Controls::SplitterBar(m_data->pCanvas);
  	split->Dock(Gwen::Pos::Center);
  	split->SetHeight(300);
  	split->SetWidth(300);
  	*/
  	/*
  
  
  	*/
  
  	Gwen::Controls::ScrollControl* windowLeft = new Gwen::Controls::ScrollControl(m_data->pCanvas);
  	windowLeft->Dock(Gwen::Pos::Left);
  	//	windowLeft->SetTitle("title");
  	windowLeft->SetScroll(false, false);
  	windowLeft->SetWidth(250);
  	windowLeft->SetPos(50, 50);
  	windowLeft->SetHeight(500);
  	//windowLeft->SetClosable(false);
  	//	windowLeft->SetShouldDrawBackground(true);
  	windowLeft->SetTabable(true);
  
  	Gwen::Controls::TabControl* explorerTab = new Gwen::Controls::TabControl(windowLeft);
  
  	//tab->SetHeight(300);
  //	explorerTab->SetWidth(230);
  	explorerTab->SetHeight(250);
  	//tab->Dock(Gwen::Pos::Left);
  	explorerTab->Dock(Gwen::Pos::Fill);
  
  	
  
  
  
  	//m_data->m_exampleInfoTextOutput->SetBounds(2, 10, 236, 400);
  
  	//windowRight
  
  	Gwen::UnicodeString explorerStr1(L"Explorer");
  	m_data->m_explorerPage = explorerTab->AddPage(explorerStr1);
  	Gwen::UnicodeString shapesStr1(L"Shapes");
  	explorerTab->AddPage(shapesStr1);
  	Gwen::UnicodeString testStr1(L"Test");
  	explorerTab->AddPage(testStr1);
  
  	Gwen::Controls::TreeControl* ctrl = new Gwen::Controls::TreeControl(m_data->m_explorerPage->GetPage());
  	m_data->m_explorerTreeCtrl = ctrl;
  	ctrl->SetKeyboardInputEnabled(true);
  	ctrl->Focus();
  	ctrl->SetBounds(2, 10, 236, 300);
  
  		m_data->m_exampleInfoGroupBox = new Gwen::Controls::Label( m_data->m_explorerPage->GetPage() );
  	m_data->m_exampleInfoGroupBox->SetPos(2, 314);
  	m_data->m_exampleInfoGroupBox->SetHeight( 15 );
  	m_data->m_exampleInfoGroupBox->SetWidth(234);
  	m_data->m_exampleInfoGroupBox->SetText("Example Description");
  
  	m_data->m_exampleInfoTextOutput = new Gwen::Controls::ListBox(m_data->m_explorerPage->GetPage());
  	
  
  	//m_data->m_exampleInfoTextOutput->Dock( Gwen::Pos::Bottom );
  	m_data->m_exampleInfoTextOutput->SetPos(2, 332);
  	m_data->m_exampleInfoTextOutput->SetHeight( 150 );
  	m_data->m_exampleInfoTextOutput->SetWidth(233);
  	
  
     
  }
  
  void	GwenUserInterface::forceUpdateScrollBars()
  {
  	b3Assert(m_data);
  	b3Assert(m_data->m_explorerTreeCtrl);
  	if (m_data && m_data->m_explorerTreeCtrl)
  	{
  		m_data->m_explorerTreeCtrl->ForceUpdateScrollBars();
  	}
  }
  
  void	GwenUserInterface::setFocus()
  {
  	b3Assert(m_data);
  	b3Assert(m_data->m_explorerTreeCtrl);
  	if (m_data && m_data->m_explorerTreeCtrl)
  	{
  		m_data->m_explorerTreeCtrl->Focus();
  	}
  }
  
  b3ToggleButtonCallback	GwenUserInterface::getToggleButtonCallback()
  {
  	return m_data->m_toggleButtonCallback;
  }
  
  void	GwenUserInterface::setToggleButtonCallback(b3ToggleButtonCallback callback)
  {
  	m_data->m_toggleButtonCallback = callback;
  }
  void	GwenUserInterface::registerToggleButton(int buttonId, const char* name)
  {
  	assert(m_data);
  	assert(m_data->m_demoPage);
  
  	Gwen::Controls::Button* but = new Gwen::Controls::Button(m_data->m_demoPage->GetPage());
  
  	///some heuristic to find the button location
  	int ypos = m_data->m_curYposition;
  	but->SetPos(10, ypos );
  	but->SetWidth( 100 );
  	//but->SetBounds( 200, 30, 300, 200 );
  
  	MyButtonHander* handler = new MyButtonHander(m_data, buttonId);
  	m_data->m_handlers.push_back(handler);
  	m_data->m_curYposition+=22;
  	but->onToggle.Add(handler, &MyButtonHander::onButtonA);
  	but->SetIsToggle(true);
  	but->SetToggleState(false);
  	but->SetText(name);
  
  }
  
  void	GwenUserInterface::setComboBoxCallback(b3ComboBoxCallback callback)
  {
  	m_data->m_comboBoxCallback = callback;
  }
  
  b3ComboBoxCallback GwenUserInterface::getComboBoxCallback()
  {
  	return m_data->m_comboBoxCallback;
  }
  void	GwenUserInterface::registerComboBox(int comboboxId, int numItems, const char** items, int startItem)
  {
  	Gwen::Controls::ComboBox* combobox = new Gwen::Controls::ComboBox(m_data->m_demoPage->GetPage());
  	MyComboBoxHander* handler = new MyComboBoxHander(m_data, comboboxId);
  	m_data->m_handlers.push_back(handler);
  
  	combobox->onSelection.Add(handler,&MyComboBoxHander::onSelect);
  	int ypos = m_data->m_curYposition;
  	combobox->SetPos(10, ypos );
  	combobox->SetWidth( 100 );
  	//box->SetPos(120,130);
  	for (int i=0;i<numItems;i++)
  	{
  		Gwen::Controls::MenuItem* item = combobox->AddItem(Gwen::Utility::StringToUnicode(items[i]));
  		if (i==startItem)
  			combobox->OnItemSelected(item);
  	}
  
  	m_data->m_curYposition+=22;
  
  
  
  }
  
  void	GwenUserInterface::draw(int width, int height)
  {
  
  //	printf("width = %d, height=%d\n", width,height);
  	if (m_data->pCanvas)
  	{
  		m_data->pCanvas->SetSize(width,height);
  		//m_data->m_primRenderer->setScreenSize(width,height);
  		m_data->pRenderer->Resize(width,height);
  		m_data->pCanvas->RenderCanvas();
  		//restoreOpenGLState();
  	}
  
  }
  
  bool	GwenUserInterface::mouseMoveCallback( float x, float y)
  {
  	bool handled  = false;
  
  	static int m_lastmousepos[2] = {0,0};
  	static bool isInitialized = false;
  	if (m_data->pCanvas)
  	{
  		if (!isInitialized)
  		{
  			isInitialized = true;
  			m_lastmousepos[0] = x+1;
  			m_lastmousepos[1] = y+1;
  		}
  		handled = m_data->pCanvas->InputMouseMoved(x,y,m_lastmousepos[0],m_lastmousepos[1]);
  	}
  	return handled;
  
  }
  #include "../CommonInterfaces/CommonWindowInterface.h"
  
  bool	GwenUserInterface::keyboardCallback(int bulletKey, int state)
  {
  	int key = -1;
  	if (m_data->pCanvas)
  	{
  		//convert 'Bullet' keys into 'Gwen' keys
  		switch (bulletKey)
  		{
  		case B3G_RETURN:
  		{
  				   key = Gwen::Key::Return;
  				   break;
  		}
  		case 	B3G_LEFT_ARROW:
  			key = Gwen::Key::Left;
  			break;
  		case B3G_RIGHT_ARROW:
  			key = Gwen::Key::Right;
  			break;
  
  		case	B3G_UP_ARROW:
  			key = Gwen::Key::Up;
  			break;
  		case B3G_DOWN_ARROW:
  			key = Gwen::Key::Down;
  			break;
  		default:
  		{
  
  		}
  		};
  		bool bDown = (state == 1);
  
  		return m_data->pCanvas->InputKey(key, bDown);
  	}
  	return false;
  }
  
  
  bool	GwenUserInterface::mouseButtonCallback(int button, int state, float x, float y)
  {
  	bool handled = false;
  	if (m_data->pCanvas)
  	{
  		handled = m_data->pCanvas->InputMouseMoved(x,y,x, y);
  
  		if (button>=0)
  		{
  			handled = m_data->pCanvas->InputMouseButton(button,(bool)state);
  			if (handled)
  			{
  				//if (!state)
  				//	return false;
  			}
  		}
  	}
  	return handled;
  }
  