#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