Newer
Older
Import / research / ui / TweakableProperties / toolkit / src / GL / Program.cpp
#include <string>
#include <vector>
#include <ctype.h>

#include "GL/Program.h"
#include "GL/TextView.h"
#include "GL/TreeView.h"
#include "GL/Context.h"
#include "GL/Math.h"
#include "GL/Font.h"
#include "GL/Nodes.h"
#include "GL/Menu.h"
#include "GL/Shaders.h"
#include "GL/Cubes.h"
#include "GL/ImmediateMode.h"
#include "GL/PythonTests.h"
#include "GL/LineDrawing.h"
#include "GL/Objects.h"


BEGIN_NAMESPACE


Menu mainMenu;
std::vector<NodePanel*>	panels;
std::vector<Connection>	connections;
TextView *view = 0;
TreeView<Object> *tree = 0;


bool editingConnection = false;
NodePanel* editingConnectionPanel = 0;
int editingConnectionType = 0;  // 0 -> input type,  1 -> output type
int editingConnectionSlotIndex = 0;

GLuint texture;
float g_zoomFactor = 1.0;
float g_xOff = 0.0;
float g_yOff = 0.0;
int mouseX, mouseY, mouseButtons;


const char* menuItems = R"foo(

File
  New...
  Open...
  Open Recent...
  Revert
  Recover Last Session
  Recover Auto Save...
  ----------------------
  Recent              >
    Foo.txt
    Blah.txt
  ----------------------
  Save
  Save As...
  Save Copy...
  ----------------------
  Quit

Edit
  Undo
  Redo
  ----------------------
  Cut
  Copy
  Paste
  ----------------------
  Select All

View
  Full Screen
  Log

Help
  View Help
  About

)foo";


void AppMouseUpdate(int a_mouseX, int a_mouseY, int a_buttons, MouseButtons a_mouseButtons, MouseState a_mouseState)
{
	mouseX = int((a_mouseX / g_zoomFactor) - g_xOff);
	mouseY = int((a_mouseY / g_zoomFactor) - g_yOff);
	mouseButtons = a_buttons;

	for (unsigned i = 0; i < panels.size(); ++i) {

		if ( panels[i]->highlighted ) {
			panels[i]->x = mouseX - panels[i]->xDragStart;
			panels[i]->y = mouseY - panels[i]->yDragStart;
		}

		if (a_mouseButtons == MB_Left && a_mouseState == MS_Up ) {
			panels[i]->highlighted = false;
		}

		int x, y, w, h;
		panels[i]->GetTitleBarArea(x, y, w, h);
		if (mouseX >= x && mouseX < (x+w) && mouseY >= y && mouseY < (y+h)) {
			// over titlebar
			if (a_mouseButtons == MB_Left && a_mouseState == MS_Down ) {
				panels[i]->xDragStart = mouseX - x;
				panels[i]->yDragStart = mouseY - y;
				panels[i]->highlighted = true;
			}
		}
		for (unsigned s = 0; s < panels[i]->m_inputs.size(); ++s) {
			panels[i]->GetInputSlotPosition(s, x, y);
			if (((mouseX - x)*(mouseX - x)+(mouseY - y)*(mouseY - y)) < 10*10) {
				// over input slot
				if (a_mouseButtons == MB_Left && a_mouseState == MS_Up ) {
					if (editingConnectionPanel != panels[i] && editingConnection && editingConnectionType ) {
						bool foundExistingConnection = false;
						for (unsigned c = 0; c < connections.size(); ++c) {
							if (connections[c].inputPanel == panels[i] && (int)s == connections[c].input) {
								connections[c].outputPanel = editingConnectionPanel;
								connections[c].output = editingConnectionSlotIndex;
								foundExistingConnection = true;
								break;
							}
						}
						if (!foundExistingConnection) {
							Connection con(editingConnectionPanel, editingConnectionSlotIndex, panels[i], s);
							connections.push_back(con);
						}
					}
					editingConnection = false;
					break;
				}
				if (a_mouseButtons == MB_Left && a_mouseState == MS_Down ) {
					editingConnection = true;
					editingConnectionPanel = panels[i];
					editingConnectionType = 0;
					editingConnectionSlotIndex = s;
					for (unsigned c = 0; c < connections.size(); ++c) {
						if (connections[c].inputPanel == panels[i] && (int)s == connections[c].input) {
							editingConnectionPanel = connections[c].outputPanel;
							editingConnectionType = 1;
							editingConnectionSlotIndex = connections[c].output;

							// remove it
							connections[c] = connections.back();
							connections.pop_back();
							break;
						}
					}
					break;
				}
			}
		}
		for (unsigned s = 0; s < panels[i]->m_outputs.size(); ++s) {
			panels[i]->GetOutputSlotPosition(s, x, y);
			if (((mouseX - x)*(mouseX - x)+(mouseY - y)*(mouseY - y)) < 10*10) {
				// over output slot
				if (a_mouseButtons == MB_Left && a_mouseState == MS_Up ) {
					if (editingConnectionPanel != panels[i] && editingConnection && !editingConnectionType ) {
						Connection con(panels[i], s, editingConnectionPanel, editingConnectionSlotIndex);
						connections.push_back(con);
					}
					editingConnection = false;
					break;
				}
				if (a_mouseButtons == MB_Left && a_mouseState == MS_Down ) {
					editingConnection = true;
					editingConnectionPanel = panels[i];
					editingConnectionType = 1;
					editingConnectionSlotIndex = s;
					break;
				}
			}
		}
	}

	if (a_mouseButtons == MB_Left && a_mouseState == MS_Up ) {
		editingConnection = false;
	}
}



void AppPaint(CUTE::CUTE_PaintTarget a_target)
{
	glClearColor(0.25, 0.25, 0.25, 1.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glDisable(GL_DEPTH_TEST);

	glShadeModel(GL_SMOOTH);
	glEnable(GL_LINE_SMOOTH);
	glEnable(GL_POLYGON_SMOOTH);
	/*
	glEnable(GL_POINT_SMOOTH);
	glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
	glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
	glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
	*/

	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


	glLineWidth(0.75);

	//glShadeModel(GL_FLAT);
	//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	glOrtho(0, (a_target.m_width-1.0f)/g_zoomFactor, (a_target.m_height-1.0f)/g_zoomFactor, 0, -1, 1);
	glTranslatef((0.5f/g_zoomFactor-0.5f)*a_target.m_width, (0.5f/g_zoomFactor-0.5f)*a_target.m_height, 0.0f);

	g_xOff = (0.5f/g_zoomFactor-0.5f)*a_target.m_width;
	g_yOff = (0.5f/g_zoomFactor-0.5f)*a_target.m_height;

	//glTranslatef(-1.0, 1.0, 0.0);
	//glScalef(2.0 * g_zoomFactor / a_target.m_width, -2.0 * g_zoomFactor / a_target.m_height, 1.0f);
	

	// Draw grid
	for (int i = 0; i < a_target.m_width; i += 25)
		glDrawLine((float)i, 0, (float)i, (float)a_target.m_height, 0x20000000);
	for (int j = 0; j < a_target.m_height; j += 25)
		glDrawLine(0, (float)j, (float)a_target.m_width, (float)j, 0x20000000);

	// Draws the target buffer
	//glDrawTarget(0.0, 0.0, a_target);

	// Draws test shapes
	/*
	glDrawLine(10, 10, a_target.m_width - 10, a_target.m_height - 10, 0x00ff00);
	glDrawCurvedLine(10, 10, a_target.m_width - 10, a_target.m_height - 10, 0x00ffff);
	glDrawCurvedLine(a_target.m_width - 10, 10, 10, a_target.m_height - 10, 0x00ffff);
	glDrawRect(100, 100, a_target.m_width - 100, a_target.m_height - 100, 0x00ff00);
	glDrawCircle(150, 150, a_target.m_height - 150, 0x00ff00);
	//glPixelZoom(g_zoomFactor, g_zoomFactor);
	glDrawText(30, 50, "Hello World", 0xff000000, 0xffffffff, 15);
	glDrawFillRect(x, y, x+w, y+h, 0x808080);
	*/

	for (unsigned i = 0; i < connections.size(); ++i)
		connections[i].draw();

	glCheckErrors();

	if (editingConnection)
	{
		int x, y;
		if (editingConnectionType) {
			editingConnectionPanel->GetOutputSlotPosition(editingConnectionSlotIndex, x, y);
			glDrawStyledCurvedLine((float)x, (float)y, (float)mouseX, (float)mouseY, g_zoomFactor, true);
		} else {
			editingConnectionPanel->GetInputSlotPosition(editingConnectionSlotIndex, x, y);
			glDrawStyledCurvedLine((float)mouseX, (float)mouseY, (float)x, (float)y, g_zoomFactor, true);
		}
	}

	glCheckErrors();

	for (unsigned i = 0; i < panels.size(); ++i)
		panels[i]->draw();

	glCheckErrors();

	mainMenu.x = 0;
	mainMenu.y = 20;
	mainMenu.w = a_target.m_width;
	mainMenu.draw();

	view->text = "Blah blah blah the quick brown fox jumps over the lazy dog. Blah blah break\nthe quick brown tab\t fox jumps over the lazy dog. Blah blah blah the quick brown fox jumps over the lazy dog. Blahblahthequickbrownfoxjumpsoverthelazydog. Blahblahthequickbrownfoxjumpsoverthelazydog. Blahblahthequickbrownfoxjumpsoverthelazydog.";
	//view->draw();
	
	tree->draw();

	// DrawShaderObjects();
	
	DrawCubes();

	// LineDrawingTests();

	glCheckErrors();

	SwapBuffers(wglGetCurrentDC());
}


void AppInit(HWND a_hwnd, CUTE::CUTE_PaintTarget a_target)
{
	// Create the GL context
	glWMCreate(a_hwnd);
	glCheckErrors();
	glLoadExtensions();
	glInitFont();
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	int w = a_target.m_strideBytes/4;
	int h = nextPowerOfTwo(a_target.m_height);
	glGenTextures(1, &texture);
	glCheckErrors();
	glBindTexture(GL_TEXTURE_2D, texture);
	glCheckErrors();
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // GL_LINEAR_MIPMAP_LINEAR); // Linear Filtering
	glCheckErrors();
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
	glCheckErrors();
	glTexImage2D(GL_TEXTURE_2D, 0, 3, w, h, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, a_target.m_pixels);
	glCheckErrors();

	SetupObjects();
	SetupCubes();

	view->x = a_target.m_width * 3 / 4;
	view->w = a_target.m_width / 4;
	view->y = a_target.m_height / 4;
	view->h = a_target.m_height * 3 / 4;

	tree->x = a_target.m_width * 3 / 4;
	tree->w = a_target.m_width / 4;
	tree->y = a_target.m_height / 4;
	tree->h = a_target.m_height * 3 / 4;
}


void AppDestroy(HWND a_hwnd)
{
	glDeleteTextures(1, &texture);

	glCleanupFont();
	CleanupObjects();

	// Destroy the GL context
	glWMDestroy(a_hwnd);
	//ReleaseDC(a_hwnd, m_data->m_handle);
	//if (m_data->m_glContext)
		//wglDeleteContext(m_data->m_glContext);
}


void AppWheelUpdate(int a_wheel)
{
	if (a_wheel > 0)
		g_zoomFactor *= 1.3f;
	else
		g_zoomFactor *= 0.7f;
	g_zoomFactor = (g_zoomFactor >= 10.0f) ? 10.0f : g_zoomFactor;
}


void AppContruct()
{
	// PythonTests();

	NodePanel *panelA = new NodePanel(110, 110, 150, 200, "Dot Product");
	NodePanel *panelB = new NodePanel(410, 200, 150, 200, "Multiply");
	NodePanel *panelC = new NodePanel(610, 200, 150, 200, "Random");

	panelA->addInput("Vector");
	panelA->addInput("Vector");
	panelA->addOutput("Scalar");
	
	panelB->addInput("Value");
	panelB->addInput("Scalar");
	panelB->addOutput("Value");
	panelB->addOutput("Vector");

	panelC->addInput("Seed");
	panelC->addInput("Range");
	panelC->addOutput("Value");
	panelC->addOutput("Randomness");

	panels.push_back(panelA);
	panels.push_back(panelB);
	panels.push_back(panelC);

	/*
	Connection connection(*panelA, 0, *panelB, 1);
	connections.push_back(connection);
	*/

	mainMenu.initFromStringList(menuItems, ARRAY_SIZE(menuItems));

	tree = new TreeView<Object>(g_objectTree, 700, 200, 200, 600, "Object Explorer");	
	view = new TextView(700, 200, 200, 600, "Text View");
}


END_NAMESPACE