1 
2 #include "gwenUserInterface.h"
3 #include "gwenInternalData.h"
4 #include "Gwen/Controls/ImagePanel.h"
5 #include "Gwen/Controls/ColorPicker.h"
6 //#include "Gwen/Controls/HSVColorPicker.h"
7 
8 class MyGraphWindow* graphWindow = 0;
9 
GwenUserInterface()10 GwenUserInterface::GwenUserInterface()
11 {
12 	m_data = new GwenInternalData();
13 	m_data->m_toggleButtonCallback = 0;
14 	m_data->m_comboBoxCallback = 0;
15 }
16 
17 class MyMenuItems : public Gwen::Controls::Base
18 {
19 public:
20 	b3FileOpenCallback m_fileOpenCallback;
21 	b3QuitCallback m_quitCallback;
22 
MyMenuItems()23 	MyMenuItems() : Gwen::Controls::Base(0), m_fileOpenCallback(0)
24 	{
25 	}
myQuitApp(Gwen::Controls::Base * pControl)26 	void myQuitApp(Gwen::Controls::Base* pControl)
27 	{
28 		if (m_quitCallback)
29 		{
30 			(*m_quitCallback)();
31 		}
32 	}
fileOpen(Gwen::Controls::Base * pControl)33 	void fileOpen(Gwen::Controls::Base* pControl)
34 	{
35 		if (m_fileOpenCallback)
36 		{
37 			(*m_fileOpenCallback)();
38 		}
39 	}
40 };
41 
42 struct MyTestMenuBar : public Gwen::Controls::MenuStrip
43 {
44 	Gwen::Controls::MenuItem* m_fileMenu;
45 	Gwen::Controls::MenuItem* m_viewMenu;
46 	MyMenuItems* m_menuItems;
47 
MyTestMenuBarMyTestMenuBar48 	MyTestMenuBar(Gwen::Controls::Base* pParent)
49 		: Gwen::Controls::MenuStrip(pParent)
50 	{
51 		//		Gwen::Controls::MenuStrip* menu = new Gwen::Controls::MenuStrip( pParent );
52 		{
53 			m_menuItems = new MyMenuItems();
54 			m_menuItems->m_fileOpenCallback = 0;
55 			m_menuItems->m_quitCallback = 0;
56 
57 			m_fileMenu = AddItem(L"File");
58 
59 			m_fileMenu->GetMenu()->AddItem(L"Open", m_menuItems, (Gwen::Event::Handler::Function)&MyMenuItems::fileOpen);
60 			m_fileMenu->GetMenu()->AddItem(L"Quit", m_menuItems, (Gwen::Event::Handler::Function)&MyMenuItems::myQuitApp);
61 			m_viewMenu = AddItem(L"View");
62 		}
63 	}
~MyTestMenuBarMyTestMenuBar64 	virtual ~MyTestMenuBar()
65 	{
66 		delete m_menuItems;
67 	}
68 };
69 
exit()70 void GwenUserInterface::exit()
71 {
72 	//m_data->m_menubar->RemoveAllChildren();
73 	delete m_data->m_tab;
74 	delete m_data->m_windowRight;
75 	delete m_data->m_leftStatusBar;
76 	delete m_data->m_TextOutput;
77 	delete m_data->m_rightStatusBar;
78 	delete m_data->m_bar;
79 	delete m_data->m_menubar;
80 
81 	m_data->m_menubar = 0;
82 	delete m_data->pCanvas;
83 	m_data->pCanvas = 0;
84 }
85 
~GwenUserInterface()86 GwenUserInterface::~GwenUserInterface()
87 {
88 	for (int i = 0; i < m_data->m_handlers.size(); i++)
89 	{
90 		delete m_data->m_handlers[i];
91 	}
92 
93 	m_data->m_handlers.clear();
94 
95 	delete m_data;
96 }
97 
resize(int width,int height)98 void GwenUserInterface::resize(int width, int height)
99 {
100 	m_data->pCanvas->SetSize(width, height);
101 }
102 
103 struct MyComboBoxHander : public Gwen::Event::Handler
104 {
105 	GwenInternalData* m_data;
106 	int m_buttonId;
107 
MyComboBoxHanderMyComboBoxHander108 	MyComboBoxHander(GwenInternalData* data, int buttonId)
109 		: m_data(data),
110 		  m_buttonId(buttonId)
111 	{
112 	}
113 
onSelectMyComboBoxHander114 	void onSelect(Gwen::Controls::Base* pControl)
115 	{
116 		Gwen::Controls::ComboBox* but = (Gwen::Controls::ComboBox*)pControl;
117 
118 		Gwen::String str = Gwen::Utility::UnicodeToString(but->GetSelectedItem()->GetText());
119 
120 		if (m_data->m_comboBoxCallback)
121 			(*m_data->m_comboBoxCallback)(m_buttonId, str.c_str());
122 	}
123 };
124 
125 struct MyButtonHander : public Gwen::Event::Handler
126 {
127 	GwenInternalData* m_data;
128 	int m_buttonId;
129 
MyButtonHanderMyButtonHander130 	MyButtonHander(GwenInternalData* data, int buttonId)
131 		: m_data(data),
132 		  m_buttonId(buttonId)
133 	{
134 	}
135 
onButtonAMyButtonHander136 	void onButtonA(Gwen::Controls::Base* pControl)
137 	{
138 		Gwen::Controls::Button* but = (Gwen::Controls::Button*)pControl;
139 		//		int dep = but->IsDepressed();
140 		int tog = but->GetToggleState();
141 		if (m_data->m_toggleButtonCallback)
142 			(*m_data->m_toggleButtonCallback)(m_buttonId, tog);
143 	}
144 };
145 
textOutput(const char * message)146 void GwenUserInterface::textOutput(const char* message)
147 {
148 	Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(message);
149 	m_data->m_TextOutput->AddItem(msg);
150 	m_data->m_TextOutput->Scroller()->ScrollToBottom();
151 }
152 
setExampleDescription(const char * message)153 void GwenUserInterface::setExampleDescription(const char* message)
154 {
155 	//Gwen apparently doesn't have text/word wrap, so do rudimentary brute-force implementation here.
156 
157 	std::string wrapmessage = message;
158 	int startPos = 0;
159 
160 	std::string lastFit = "";
161 	bool hasSpace = false;
162 	std::string lastFitSpace = "";
163 	int spacePos = 0;
164 
165 	m_data->m_exampleInfoTextOutput->Clear();
166 	int fixedWidth = m_data->m_exampleInfoTextOutput->GetBounds().w - 25;
167 	int wrapLen = int(wrapmessage.length());
168 	for (int endPos = 0; endPos <= wrapLen; endPos++)
169 	{
170 		std::string sub = wrapmessage.substr(startPos, (endPos - startPos));
171 		Gwen::Point pt = m_data->pRenderer->MeasureText(m_data->pCanvas->GetSkin()->GetDefaultFont(), sub);
172 
173 		if (pt.x <= fixedWidth)
174 		{
175 			lastFit = sub;
176 
177 			if (message[endPos] == ' ' || message[endPos] == '.' || message[endPos] == ',')
178 			{
179 				hasSpace = true;
180 				lastFitSpace = sub;
181 				spacePos = endPos;
182 			}
183 		}
184 		else
185 		{
186 			//submit and
187 			if (hasSpace)
188 			{
189 				endPos = spacePos + 1;
190 				hasSpace = false;
191 				lastFit = lastFitSpace;
192 				startPos = endPos;
193 			}
194 			else
195 			{
196 				startPos = endPos - 1;
197 			}
198 			Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(lastFit);
199 
200 			m_data->m_exampleInfoTextOutput->AddItem(msg);
201 			m_data->m_exampleInfoTextOutput->Scroller()->ScrollToBottom();
202 		}
203 	}
204 
205 	if (lastFit.length())
206 	{
207 		Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(lastFit);
208 		m_data->m_exampleInfoTextOutput->AddItem(msg);
209 		m_data->m_exampleInfoTextOutput->Scroller()->ScrollToBottom();
210 	}
211 }
212 
setStatusBarMessage(const char * message,bool isLeft)213 void GwenUserInterface::setStatusBarMessage(const char* message, bool isLeft)
214 {
215 	Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(message);
216 	if (isLeft)
217 	{
218 		m_data->m_leftStatusBar->SetText(msg);
219 	}
220 	else
221 	{
222 		m_data->m_rightStatusBar->SetText(msg);
223 	}
224 }
225 
registerFileOpenCallback(b3FileOpenCallback callback)226 void GwenUserInterface::registerFileOpenCallback(b3FileOpenCallback callback)
227 {
228 	m_data->m_menuItems->m_fileOpenCallback = callback;
229 }
230 
registerQuitCallback(b3QuitCallback callback)231 void GwenUserInterface::registerQuitCallback(b3QuitCallback callback)
232 {
233 	m_data->m_menuItems->m_quitCallback = callback;
234 }
235 
init(int width,int height,Gwen::Renderer::Base * renderer,float retinaScale)236 void GwenUserInterface::init(int width, int height, Gwen::Renderer::Base* renderer, float retinaScale)
237 {
238 	m_data->m_curYposition = 20;
239 	//m_data->m_primRenderer = new GLPrimitiveRenderer(width,height);
240 	m_data->pRenderer = renderer;  //new GwenOpenGL3CoreRenderer(m_data->m_primRenderer,stash,width,height,retinaScale);
241 
242 	m_data->skin.SetRender(m_data->pRenderer);
243 
244 	m_data->pCanvas = new Gwen::Controls::Canvas(&m_data->skin);
245 	m_data->pCanvas->SetSize(width, height);
246 	m_data->pCanvas->SetDrawBackground(false);
247 	m_data->pCanvas->SetBackgroundColor(Gwen::Color(150, 170, 170, 255));
248 
249 	MyTestMenuBar* menubar = new MyTestMenuBar(m_data->pCanvas);
250 	m_data->m_viewMenu = menubar->m_viewMenu;
251 	m_data->m_menuItems = menubar->m_menuItems;
252 	m_data->m_menubar = menubar;
253 
254 	Gwen::Controls::StatusBar* bar = new Gwen::Controls::StatusBar(m_data->pCanvas);
255 	m_data->m_bar = bar;
256 
257 	m_data->m_rightStatusBar = new Gwen::Controls::Label(bar);
258 
259 	m_data->m_rightStatusBar->SetWidth(width / 2);
260 	//m_data->m_rightStatusBar->SetText( L"Label Added to Right" );
261 	bar->AddControl(m_data->m_rightStatusBar, true);
262 
263 	m_data->m_TextOutput = new Gwen::Controls::ListBox(m_data->pCanvas);
264 
265 	m_data->m_TextOutput->Dock(Gwen::Pos::Bottom);
266 	m_data->m_TextOutput->SetHeight(100);
267 
268 	m_data->m_leftStatusBar = new Gwen::Controls::Label(bar);
269 
270 	//m_data->m_leftStatusBar->SetText( L"Label Added to Left" );
271 	m_data->m_leftStatusBar->SetWidth(width / 2);
272 	bar->AddControl(m_data->m_leftStatusBar, false);
273 
274 	//Gwen::KeyboardFocus
275 	/*Gwen::Controls::GroupBox* box = new Gwen::Controls::GroupBox(m_data->pCanvas);
276 	box->SetText("text");
277 	box->SetName("name");
278 	box->SetHeight(500);
279 	*/
280 	Gwen::Controls::ScrollControl* windowRight = new Gwen::Controls::ScrollControl(m_data->pCanvas);
281 	windowRight->Dock(Gwen::Pos::Right);
282 	windowRight->SetWidth(250);
283 	windowRight->SetHeight(250);
284 	windowRight->SetScroll(false, true);
285 	m_data->m_windowRight = windowRight;
286 
287 	//windowLeft->SetSkin(
288 	Gwen::Controls::TabControl* tab = new Gwen::Controls::TabControl(windowRight);
289 	m_data->m_tab = tab;
290 
291 	//tab->SetHeight(300);
292 	tab->SetWidth(240);
293 	tab->SetHeight(13250);
294 	//tab->Dock(Gwen::Pos::Left);
295 	tab->Dock(Gwen::Pos::Fill);
296 	//tab->SetMargin( Gwen::Margin( 2, 2, 2, 2 ) );
297 
298 	Gwen::UnicodeString str1(L"Params");
299 	m_data->m_demoPage = tab->AddPage(str1);
300 
301 	//	Gwen::UnicodeString str2(L"OpenCL");
302 	//	tab->AddPage(str2);
303 	//Gwen::UnicodeString str3(L"page3");
304 	//	tab->AddPage(str3);
305 
306 	//but->onPress.Add(handler, &MyHander::onButtonA);
307 
308 	//box->Dock(Gwen::Pos::Left);
309 
310 	/*Gwen::Controls::WindowControl* windowBottom = new Gwen::Controls::WindowControl(m_data->pCanvas);
311 	windowBottom->SetHeight(100);
312 	windowBottom->Dock(Gwen::Pos::Bottom);
313 	windowBottom->SetTitle("bottom");
314 	*/
315 	//	Gwen::Controls::Property::Text* prop = new Gwen::Controls::Property::Text(m_data->pCanvas);
316 	//prop->Dock(Gwen::Pos::Bottom);
317 	/*Gwen::Controls::SplitterBar* split = new Gwen::Controls::SplitterBar(m_data->pCanvas);
318 	split->Dock(Gwen::Pos::Center);
319 	split->SetHeight(300);
320 	split->SetWidth(300);
321 	*/
322 	/*
323 
324 
325 	*/
326 
327 	Gwen::Controls::ScrollControl* windowLeft = new Gwen::Controls::ScrollControl(m_data->pCanvas);
328 	windowLeft->Dock(Gwen::Pos::Left);
329 	//	windowLeft->SetTitle("title");
330 	windowLeft->SetScroll(false, false);
331 	windowLeft->SetWidth(250);
332 	windowLeft->SetPos(50, 50);
333 	windowLeft->SetHeight(500);
334 	//windowLeft->SetClosable(false);
335 	//	windowLeft->SetShouldDrawBackground(true);
336 	windowLeft->SetTabable(true);
337 
338 	Gwen::Controls::TabControl* explorerTab = new Gwen::Controls::TabControl(windowLeft);
339 
340 	//tab->SetHeight(300);
341 	//	explorerTab->SetWidth(230);
342 	explorerTab->SetHeight(250);
343 	//tab->Dock(Gwen::Pos::Left);
344 	explorerTab->Dock(Gwen::Pos::Fill);
345 
346 	//m_data->m_exampleInfoTextOutput->SetBounds(2, 10, 236, 400);
347 
348 	//windowRight
349 
350 	Gwen::UnicodeString explorerStr1(L"Explorer");
351 	m_data->m_explorerPage = explorerTab->AddPage(explorerStr1);
352 	Gwen::UnicodeString shapesStr1(L"Test");
353 	Gwen::Controls::TabButton* shapes = explorerTab->AddPage(shapesStr1);
354 
355 	///todo(erwincoumans) figure out why the HSV color picker is extremely slow
356 	//Gwen::Controls::HSVColorPicker* color = new Gwen::Controls::HSVColorPicker(shapes->GetPage());
357 	Gwen::Controls::ColorPicker* color = new Gwen::Controls::ColorPicker(shapes->GetPage());
358 	color->SetKeyboardInputEnabled(true);
359 
360 	Gwen::Controls::TreeControl* ctrl = new Gwen::Controls::TreeControl(m_data->m_explorerPage->GetPage());
361 	m_data->m_explorerTreeCtrl = ctrl;
362 	ctrl->SetKeyboardInputEnabled(true);
363 	ctrl->Focus();
364 	ctrl->SetBounds(2, 10, 236, 300);
365 
366 	m_data->m_exampleInfoGroupBox = new Gwen::Controls::Label(m_data->m_explorerPage->GetPage());
367 	m_data->m_exampleInfoGroupBox->SetPos(2, 314);
368 	m_data->m_exampleInfoGroupBox->SetHeight(15);
369 	m_data->m_exampleInfoGroupBox->SetWidth(234);
370 	m_data->m_exampleInfoGroupBox->SetText("Example Description");
371 
372 	m_data->m_exampleInfoTextOutput = new Gwen::Controls::ListBox(m_data->m_explorerPage->GetPage());
373 
374 	//m_data->m_exampleInfoTextOutput->Dock( Gwen::Pos::Bottom );
375 	m_data->m_exampleInfoTextOutput->SetPos(2, 332);
376 	m_data->m_exampleInfoTextOutput->SetHeight(150);
377 	m_data->m_exampleInfoTextOutput->SetWidth(233);
378 }
379 
forceUpdateScrollBars()380 void GwenUserInterface::forceUpdateScrollBars()
381 {
382 	b3Assert(m_data);
383 	b3Assert(m_data->m_explorerTreeCtrl);
384 	if (m_data && m_data->m_explorerTreeCtrl)
385 	{
386 		m_data->m_explorerTreeCtrl->ForceUpdateScrollBars();
387 	}
388 }
389 
setFocus()390 void GwenUserInterface::setFocus()
391 {
392 	b3Assert(m_data);
393 	b3Assert(m_data->m_explorerTreeCtrl);
394 	if (m_data && m_data->m_explorerTreeCtrl)
395 	{
396 		m_data->m_explorerTreeCtrl->Focus();
397 	}
398 }
399 
getToggleButtonCallback()400 b3ToggleButtonCallback GwenUserInterface::getToggleButtonCallback()
401 {
402 	return m_data->m_toggleButtonCallback;
403 }
404 
setToggleButtonCallback(b3ToggleButtonCallback callback)405 void GwenUserInterface::setToggleButtonCallback(b3ToggleButtonCallback callback)
406 {
407 	m_data->m_toggleButtonCallback = callback;
408 }
registerToggleButton2(int buttonId,const char * name)409 void GwenUserInterface::registerToggleButton2(int buttonId, const char* name)
410 {
411 	assert(m_data);
412 	assert(m_data->m_demoPage);
413 
414 	Gwen::Controls::Button* but = new Gwen::Controls::Button(m_data->m_demoPage->GetPage());
415 
416 	///some heuristic to find the button location
417 	int ypos = m_data->m_curYposition;
418 	but->SetPos(10, ypos);
419 	but->SetWidth(200);
420 	//but->SetBounds( 200, 30, 300, 200 );
421 
422 	MyButtonHander* handler = new MyButtonHander(m_data, buttonId);
423 	m_data->m_handlers.push_back(handler);
424 	m_data->m_curYposition += 22;
425 	but->onToggle.Add(handler, &MyButtonHander::onButtonA);
426 	but->SetIsToggle(true);
427 	but->SetToggleState(false);
428 	but->SetText(name);
429 }
430 
setComboBoxCallback(b3ComboBoxCallback callback)431 void GwenUserInterface::setComboBoxCallback(b3ComboBoxCallback callback)
432 {
433 	m_data->m_comboBoxCallback = callback;
434 }
435 
getComboBoxCallback()436 b3ComboBoxCallback GwenUserInterface::getComboBoxCallback()
437 {
438 	return m_data->m_comboBoxCallback;
439 }
registerComboBox2(int comboboxId,int numItems,const char ** items,int startItem)440 void GwenUserInterface::registerComboBox2(int comboboxId, int numItems, const char** items, int startItem)
441 {
442 	Gwen::Controls::ComboBox* combobox = new Gwen::Controls::ComboBox(m_data->m_demoPage->GetPage());
443 	MyComboBoxHander* handler = new MyComboBoxHander(m_data, comboboxId);
444 	m_data->m_handlers.push_back(handler);
445 
446 	combobox->onSelection.Add(handler, &MyComboBoxHander::onSelect);
447 	int ypos = m_data->m_curYposition;
448 	combobox->SetPos(10, ypos);
449 	combobox->SetWidth(100);
450 	//box->SetPos(120,130);
451 	for (int i = 0; i < numItems; i++)
452 	{
453 		Gwen::Controls::MenuItem* item = combobox->AddItem(Gwen::Utility::StringToUnicode(items[i]));
454 		if (i == startItem)
455 			combobox->OnItemSelected(item);
456 	}
457 
458 	m_data->m_curYposition += 22;
459 }
460 
draw(int width,int height)461 void GwenUserInterface::draw(int width, int height)
462 {
463 	//	printf("width = %d, height=%d\n", width,height);
464 	if (m_data->pCanvas)
465 	{
466 		m_data->pCanvas->SetSize(width, height);
467 		//m_data->m_primRenderer->setScreenSize(width,height);
468 		m_data->pRenderer->Resize(width, height);
469 		m_data->pCanvas->RenderCanvas();
470 		//restoreOpenGLState();
471 	}
472 }
473 
mouseMoveCallback(float x,float y)474 bool GwenUserInterface::mouseMoveCallback(float x, float y)
475 {
476 	bool handled = false;
477 
478 	static int m_lastmousepos[2] = {0, 0};
479 	static bool isInitialized = false;
480 	if (m_data->pCanvas)
481 	{
482 		if (!isInitialized)
483 		{
484 			isInitialized = true;
485 			m_lastmousepos[0] = x + 1;
486 			m_lastmousepos[1] = y + 1;
487 		}
488 		handled = m_data->pCanvas->InputMouseMoved(x, y, m_lastmousepos[0], m_lastmousepos[1]);
489 	}
490 	return handled;
491 }
492 #include "../CommonInterfaces/CommonWindowInterface.h"
493 
keyboardCallback(int bulletKey,int state)494 bool GwenUserInterface::keyboardCallback(int bulletKey, int state)
495 {
496 	int gwenKey = -1;
497 	if (m_data->pCanvas)
498 	{
499 		//convert 'Bullet' keys into 'Gwen' keys
500 		switch (bulletKey)
501 		{
502 			case B3G_RETURN:
503 			{
504 				gwenKey = Gwen::Key::Return;
505 				break;
506 			}
507 			case B3G_LEFT_ARROW:
508 			{
509 				gwenKey = Gwen::Key::Left;
510 				break;
511 			}
512 			case B3G_RIGHT_ARROW:
513 			{
514 				gwenKey = Gwen::Key::Right;
515 				break;
516 			}
517 			case B3G_UP_ARROW:
518 			{
519 				gwenKey = Gwen::Key::Up;
520 				break;
521 			}
522 			case B3G_DOWN_ARROW:
523 			{
524 				gwenKey = Gwen::Key::Down;
525 				break;
526 			}
527 			case B3G_BACKSPACE:
528 			{
529 				gwenKey = Gwen::Key::Backspace;
530 				break;
531 			}
532 			case B3G_DELETE:
533 			{
534 				gwenKey = Gwen::Key::Delete;
535 				break;
536 			}
537 			case B3G_HOME:
538 			{
539 				gwenKey = Gwen::Key::Home;
540 				break;
541 			}
542 			case B3G_END:
543 			{
544 				gwenKey = Gwen::Key::End;
545 				break;
546 			}
547 			case B3G_SHIFT:
548 			{
549 				gwenKey = Gwen::Key::Shift;
550 				break;
551 			}
552 			case B3G_CONTROL:
553 			{
554 				gwenKey = Gwen::Key::Control;
555 				break;
556 			}
557 
558 			default:
559 			{
560 			}
561 		};
562 
563 		if (gwenKey >= 0)
564 		{
565 			return m_data->pCanvas->InputKey(gwenKey, state == 1);
566 		}
567 		else
568 		{
569 			if (bulletKey < 256 && state)
570 			{
571 				Gwen::UnicodeChar c = (Gwen::UnicodeChar)bulletKey;
572 				return m_data->pCanvas->InputCharacter(c);
573 			}
574 		}
575 	}
576 	return false;
577 }
578 
mouseButtonCallback(int button,int state,float x,float y)579 bool GwenUserInterface::mouseButtonCallback(int button, int state, float x, float y)
580 {
581 	bool handled = false;
582 	if (m_data->pCanvas)
583 	{
584 		handled = m_data->pCanvas->InputMouseMoved(x, y, x, y);
585 
586 		if (button >= 0)
587 		{
588 			handled = m_data->pCanvas->InputMouseButton(button, (bool)state);
589 			if (handled)
590 			{
591 				//if (!state)
592 				//	return false;
593 			}
594 		}
595 	}
596 	return handled;
597 }
598