//This was written by CH_2005
//e-mail: ch_2005@programmer.net
//It requires the Carnegie Mellon Graphics Package for Dev-C++
// http://www-2.cs.cmu.edu/~cm-gfxpkg/index.html
//It was in fact written in Dev-Cpp 4.9.7.0 Which is also open source
// you can get dev-cpp from the internet
#include <iostream>
#include <fstream>
#include <conio.h>
#include <math.h>
#include "CarnegieMellonGraphics.h"
#include "colors.h"
#include <string>
#include <vector>
#include <stdlib.h>
#include <math.h>
using namespace std;
//=========GLOBALS=========
//====Create a new window 700 by 500 in size at 1034,310
Window window(20,20,700,500, "CH's VCpp 2D to 3D Wavefront OBJ Creator");
//==THIS=TELLS=WHAT=THE=PROGRAM=IS=DOING==
typedef enum {NONE,
/*FILE*/
LOAD_2D, //Loads an image to use as a guide in modling
WIDTH, //Changes default width at vert
SAVE, //Saves the OBJ model file
EXIT, //Makes the program quit
/*ADD*/
ADD_VERTS, //Adds points to the vertex array
ADD_FACES, //Adds faces to the face array by clicking verts
ADD_EDGES, //Adds edges to the edges arry by clicking verts
/*MOD*/
MOVE_VERTS, //Changes the x/y of a vert by click and drag
VERT_WIDTH, //Changes the width at a vert (z)
/*DEL*/
DEL_VERTS, //Deletes a vert from the model!(if edges|faces)
DEL_FACES, //Deletes a face by clicking 3 verts of a face
DEL_EDGES, //Deletes an edge by clicking 2 verts of an edge
/*COLORS*/
COLORS_VERTS, //Changes the draw color for verts
COLORS_FACES, //Changes the draw color for faces
COLORS_EDGES, //Changes the draw color for edges
}mode;
mode PROG_MODE;
//==MODEL=DATA!
struct vert{ //a vert holds and x,y,z set
int x;
int y;
int z;
//a pretty constructor for the struct
vert(int x, int y, int z):x(x),y(y),z(z){};
};
struct face{ //in a face the points are define a triange clockwise
int vert1;
int vert2;
int vert3;
face(int vert1, int vert2, int vert3):
vert1(vert1),vert2(vert2),vert3(vert3){};
};
struct model{ //these simpe models have just verts and faces ...
vector<vert> verts;
//int num_verts;
vector<face> faces;
//int_num_faces;
int width; //...and a default width to just be used in the editor
//the constructor only inits the width cuz the verts and faces are not known
model(int width): width(width) {};
};
model OBJ(50);
//==FONT
//Set Font and Style
//Char sizes
const int CHAR_WIDTH = 9;
const int CHAR_HEIGHT = 12;
//Foreground and Background font styles
const Style FORE_FONT_STYLE = Style(Color::BLACK,2);
const Style BACK_FONT_STYLE = Style(Color::WHITE,2);
//Font ttf file for font face
const string FONT_FACE = "C:\\WINDOWS\\FONTS\\OCRAEXT.TTF";
const Font FONT = Font(FONT_FACE,CHAR_HEIGHT);
//==CURSOR
const Style FORE_CURSOR_STYLE = Style(Color::BLACK,3);
const Style BACK_CURSOR_STYLE = Style(Color::WHITE,3);
//==RECTANGLES
struct rect{
int x1;
int y1;
int x2;
int y2;
//yay a struct constructor!
rect(int x1, int y1, int x2, int y2):
x1(x1), x2(x2), y1(y1), y2(y2) {}
};
//screen areas
// Area x1 y1 x2 y2
// ~~~~ ~~ ~~ ~~ ~~
const rect CANVAS ( 25, 87, 25+651, 87+276 ); //651x276
const rect IO_WINDOW ( 25, 399, 25+651, 76+399 ); //651x76
const rect MENU_RECT ( 376, 27, 376+314, 27+34 );
//Menu button rects
// Area x1 y1 x2 y2
// ~~~~ ~~ ~~ ~~ ~~
const rect FILE_RECT ( 380, 4, 380+48, 25);
const rect ADD_RECT ( 436, 4, 436+47, 25);
const rect MOD_RECT ( 490, 4, 490+51, 25);
const rect DEL_RECT ( 547, 4, 547+44, 25);
const rect COLORS_RECT ( 596, 4, 596+90, 25);
//SubMenu Button Rects
// Area x1 y1 x2 y2
// ~~~~ ~~ ~~ ~~ ~~
//FILE:
const rect LOAD_2D_RECT ( 383, 33, 383+86, 54);
const rect WIDTH_RECT ( 475, 33, 475+98, 54);
const rect SAVE_RECT ( 579, 33, 579+52, 54);
const rect EXIT_RECT ( 639, 33, 639+42, 54);
//ADD_DEL_COLORS:
const rect VERTS_RECT ( 391, 33, 391+58, 54);
const rect FACES_RECT ( 498, 33, 498+62, 54);
const rect EDGES_RECT ( 605, 33, 605+65, 54);
//MOD:
const rect MOVE_VERTS_RECT ( 383, 33, 383+113, 54);
const rect VERT_WIDTH_RECT ( 574, 33, 574+110, 54);
//==BUTTONS
struct menu_button{
rect my_rect;
bool enabled;
bool active;
//yay a constructor!
menu_button(rect my_rect, bool enabled, bool active):
my_rect(my_rect),enabled(enabled),active(active){}
};
//==MENU BUTTONS
// Button Rect Enabled Active
// ~~~~~~ ~~~~ ~~~~~~~ ~~~~~~
menu_button FILE_BTN ( FILE_RECT , 1 , 0 );
menu_button ADD_BTN ( ADD_RECT , 1 , 0 );
menu_button MOD_BTN ( MOD_RECT , 0 , 0 );
menu_button DEL_BTN ( DEL_RECT , 0 , 0 );
menu_button COLORS_BTN ( COLORS_RECT , 0 , 0 );
struct button{
rect my_rect;
bool enabled;
bool visable;
//yay a constructor!
button(rect my_rect, bool enabled, bool visable):
my_rect(my_rect),enabled(enabled),visable(visable){}
};
//==SUBMENU BUTTONS
// Button Rect Enabled Visable
// ~~~~~~ ~~~~ ~~~~~~~ ~~~~~~~
//FILE:
button LOAD_2D_BTN ( LOAD_2D_RECT , 0 , 0 );
button WIDTH_BTN ( WIDTH_RECT , 0 , 0 );
button SAVE_BTN ( SAVE_RECT , 0 , 0 );
button EXIT_BTN ( EXIT_RECT , 0 , 0 );
//ADD:
button ADD_VERTS_BTN ( VERTS_RECT , 0 , 0 );
button ADD_FACES_BTN ( FACES_RECT , 0 , 0 );
button ADD_EDGES_BTN ( EDGES_RECT , 0 , 0 );
//MOD:
button MOVE_VERTS_BTN ( MOVE_VERTS_RECT , 0 , 0 );
button VERT_WIDTH_BTN ( VERT_WIDTH_RECT , 0 , 0 );
//DEL:
button DEL_VERTS_BTN ( VERTS_RECT , 0 , 0 );
button DEL_FACES_BTN ( FACES_RECT , 0 , 0 );
button DEL_EDGES_BTN ( EDGES_RECT , 0 , 0 );
//COLORS:
button COLORS_VERTS_BTN ( VERTS_RECT , 0 , 0 );
button COLORS_FACES_BTN ( FACES_RECT , 0 , 0 );
button COLORS_EDGES_BTN ( EDGES_RECT , 0 , 0 );
//==COLOR SCHEME
// State Color Width
// ~~~~~ ~~~~~ ~~~~~
Style ENABLED = Style(Color:: BLUE , 2 );
Style ACTIVE = Style(Color:: GREEN , 2 );
Style HOVER = Style(Color:: RED , 2 );
Style DISABLED = Style(Color (128,0,128) , 2 );
// ~~~~~ ~~~~~ ~~~~~
Style VERT_STYLE = Style(Color:: RED , 1 );
Style FACE_STYLE = Style(Color:: GREEN , 1 );
Style EDGE_STYLE = Style(Color:: BLUE , 3 );
//==IMAGES
// Name Path Type
// ~~~~ ~~~~ ~~~~
const Image BACKGROUND_IMAGE ("ch_back.png" ,Image:: PNG );
const Image FILE_IMAGE ("ch_file.png" ,Image:: PNG );
const Image ADD_DEL_COLORS_IMAGE ("ch_add_del_colors.png" ,Image:: PNG );
const Image MOD_IMAGE ("ch_mod.png" ,Image:: PNG );
Image TEMPLATE_IMAGE;
//=========END===GLOBALS=========
//=========FUNCTIONS=========
//==BUTTON FUNCTIONS
//This should handle the border colors for a given button as well as return
//if it was clicked
bool clicked(button &to_check,const MouseEvent &m_event);
bool clicked(menu_button &to_check,const MouseEvent &m_event);
bool clicked(const rect &to_check,const MouseEvent &m_event);
void handle_buttons(const MouseEvent &m_event);
//==MENU=FUNCTIONS
//This takes care of the menus
void handle_menus(const MouseEvent &m_event);
//this activates a menu and deactivates all the others
void activate(menu_button &to_check);
//==DRAW==FUNCTIONS
void draw_model(const model &OBJ);
void draw_vert(const vert &to_draw, const Style &the_style);
void draw_vert(const vector<vert> &verts);
void draw_face(const face &to_draw, const Style &the_style);
void draw_face(const vector<face> &faces);
//==FILE=FUNCTIONS
void save_model(const model &to_save,const string &file_path);
//==MODEL=FUNCTIONS
int get_close_vert(int m_x, int m_y);
//==CLEARING FUNCTIONS
// Function to wait for a mouse click and clear the screen
void WaitNClear();
//clear the window
void clear();
//clear an area
void clear(const rect &to_clear);
//==STRING FUNCTIONS
string input_string(int line_nuber, string prompt);
string mid(string mid_of,int pos,int num_char);
//Output a strng to a given line in the io window:
void output(string message,int line_number);
//=========END====FUNCTIONS=========
//========================MAIN!==========================
int main()
{
//background:
window.drawImage(BACKGROUND_IMAGE,0,0);
//init the state of the program
PROG_MODE = NONE;
//to hold the events in the event loop
MouseEvent m_event;
KeyboardEvent k_event;
//other vars:
int m_x, m_y, i;
string prompt;
string answer;
//for finding close est vert
int dist,small_dist = 1000 ,vert1,vert2,vert3;
//event loop
//while((!window.isKeyboardQueueEmpty() && (k_event = window.getKeyboardEvent()) == KeyboardEvent() && !(k_event == KeyboardEvent(NamedKey::ESCAPE))) ^ window.isKeyboardQueueEmpty()){
while (true) {
//get mouse event now in loop
m_event = window.waitForMouseEvent();
m_x = window.getMouseX();
m_y = window.getMouseY();
//Take care of menus
handle_menus(m_event);
//Take care of buttons
handle_buttons(m_event);
switch(PROG_MODE) {
case NONE:
break;
case LOAD_2D:
//Clear the IO window
clear(IO_WINDOW);
//print the action title
output("Load 2D Template Image 651x276",1);
//set the prompt + prompt the user
prompt = "Enter PNG:";
answer = input_string(2,prompt);
//set the teplate image file name and type and display the template
TEMPLATE_IMAGE = Image(answer,Image::PNG);
window.drawImage(TEMPLATE_IMAGE,CANVAS.x1,CANVAS.y1);
//Set the prog mode back to nothing
PROG_MODE = NONE;
//clear the io window again.
clear(IO_WINDOW);
break;
case WIDTH:
//Clear the IO window
clear(IO_WINDOW);
//print the action title
output("Set Default Model Width (+/- z at each vert)",1);
//set the prompt + prompt the user
prompt = "Enter Width:";
answer = input_string(2,prompt);
//set the width
OBJ.width = atoi(answer.c_str());
//This is to make the width number updated
window.drawImage(FILE_IMAGE,MENU_RECT.x1,MENU_RECT.y1);
char width_str[20];
_ultoa(OBJ.width,width_str,10);
window.drawText(FORE_FONT_STYLE,FONT,WIDTH_BTN.my_rect.x1+70,WIDTH_BTN.my_rect.y1+15,width_str);
//Set the prog mode back to nothing
PROG_MODE = NONE;
//clear the io window again.
clear(IO_WINDOW);
break;
case SAVE:
//Clear the IO window
clear(IO_WINDOW);
//print the action title
output("Save 3D Wavefront Model OBJ File",1);
//set the prompt + prompt the user
prompt = "Enter OBJ:";
answer = input_string(2,prompt);
//save the model
save_model(OBJ,answer);
//Set the prog mode back to nothing
PROG_MODE = NONE;
//clear the io window again.
clear(IO_WINDOW);
break;
case ADD_VERTS:
if(clicked(CANVAS,m_event)) {
OBJ.verts.push_back(vert(m_x-CANVAS.x1, m_y-CANVAS.y1, OBJ.width));
OBJ.verts.push_back(vert(m_x-CANVAS.x1, m_y-CANVAS.y1, (-1)*OBJ.width));
draw_model(OBJ);
}
break;
case ADD_FACES:
if(clicked(CANVAS,m_event)) {
//get vert1 and draw it
vert1 = get_close_vert(m_x,m_y);
draw_vert(OBJ.verts[vert1],FACE_STYLE);
//get vert 2...
m_event = window.waitForMouseEvent();
m_x = window.getMouseX();
m_y = window.getMouseY();
while (!clicked(CANVAS,m_event)) {
m_event = window.waitForMouseEvent();
m_x = window.getMouseX();
m_y = window.getMouseY();
}
vert2 = get_close_vert(m_x,m_y);
//...and draw it
draw_vert(OBJ.verts[vert2],FACE_STYLE);
//get vert 3...
m_event = window.waitForMouseEvent();
m_x = window.getMouseX();
m_y = window.getMouseY();
while (!clicked(CANVAS,m_event)) {
m_event = window.waitForMouseEvent();
m_x = window.getMouseX();
m_y = window.getMouseY();
}
vert3 = get_close_vert(m_x,m_y);
//...and draw it
draw_vert(OBJ.verts[vert3],FACE_STYLE);
OBJ.faces.push_back(face(vert1,vert2,vert3));
OBJ.faces.push_back(face(vert3+1,vert2+1,vert1+1));
draw_model(OBJ);
}
break;
case ADD_EDGES:
if(clicked(CANVAS,m_event)) {
//get vert1 and draw it
vert1 = get_close_vert(m_x,m_y);
draw_vert(OBJ.verts[vert1],EDGE_STYLE);
//get vert 2...
m_event = window.waitForMouseEvent();
m_x = window.getMouseX();
m_y = window.getMouseY();
while (!clicked(CANVAS,m_event)) {
m_event = window.waitForMouseEvent();
m_x = window.getMouseX();
m_y = window.getMouseY();
}
vert2 = get_close_vert(m_x,m_y);
//...and draw it
draw_vert(OBJ.verts[vert2],EDGE_STYLE);
OBJ.faces.push_back(face(vert2,vert1,vert2+1));
OBJ.faces.push_back(face(vert1+1,vert2+1,vert1));
draw_face(OBJ.faces[OBJ.faces.size()-1],EDGE_STYLE);
draw_model(OBJ);
}
break;
case EXIT:
//destruct some stuff
window.~Window();
FONT.~Font();
BACKGROUND_IMAGE.~Image();
FILE_IMAGE.~Image();
ADD_DEL_COLORS_IMAGE.~Image();
MOD_IMAGE.~Image();
TEMPLATE_IMAGE.~Image();
return 0;
break;
}
}
return 0;
}
//========================END===MAIN!==========================
int get_close_vert(int m_x, int m_y) {
int close_vert, small_dist = 10000, dist;
for(int i = 0; i < OBJ.verts.size();i+=2) {
dist = sqrt(double((OBJ.verts[i].x - (m_x-CANVAS.x1)))*(OBJ.verts[i].x - (m_x-CANVAS.x1)) + (OBJ.verts[i].y - (m_y-CANVAS.y1))*(OBJ.verts[i].y - (m_y-CANVAS.y1)));
//massive debug output :-)
/*cout << OBJ.verts[i].x << '\t' << (OBJ.verts[i].x - m_x) << '\t' << (OBJ.verts[i].x - m_x)*(OBJ.verts[i].x - m_x)
<< '\t' << OBJ.verts[i].y << '\t' << (OBJ.verts[i].y - m_y) << '\t' << (OBJ.verts[i].y - m_y)*(OBJ.verts[i].y - m_y)
<< endl << (OBJ.verts[i].x - m_x)*(OBJ.verts[i].x - m_x) + (OBJ.verts[i].y - m_y)*(OBJ.verts[i].y - m_y)
<< '\t' << double((OBJ.verts[i].x - m_x))*(OBJ.verts[i].x - m_x) + (OBJ.verts[i].y - m_y)*(OBJ.verts[i].y - m_y)
<< '\t' << sqrt(double((OBJ.verts[i].x - m_x))*(OBJ.verts[i].x - m_x) + (OBJ.verts[i].y - m_y)*(OBJ.verts[i].y - m_y))
<< endl << endl;*/
if (dist < small_dist) {
small_dist = dist;
close_vert = i;
}
}
return close_vert;
}
void save_model(const model &to_save,const string &file_path) {
ofstream ofile;
ofile.open(file_path.c_str());
for(int i = 0; i < to_save.verts.size(); i++)
ofile << "v "
<< to_save.verts[i].x << ' '
<< to_save.verts[i].y << ' '
<< to_save.verts[i].z << '\n';
for(int i = 0; i < to_save.faces.size(); i++)
ofile << "f "
<< to_save.faces[i].vert1+1 << ' '
<< to_save.faces[i].vert2+1 << ' '
<< to_save.faces[i].vert3+1 << '\n';
ofile.close();
}
void draw_model(const model &obj){
draw_face(obj.faces);
draw_vert(obj.verts);
}
void draw_face(const vector<face> &faces){
for(int i = 0; i < faces.size();i++) {
draw_face(faces[i],FACE_STYLE);
}
}
void draw_face(const face &to_draw, const Style &the_style) {
window.drawLine(the_style,OBJ.verts[to_draw.vert1].x+CANVAS.x1,OBJ.verts[to_draw.vert1].y+CANVAS.y1,OBJ.verts[to_draw.vert2].x+CANVAS.x1,OBJ.verts[to_draw.vert2].y+CANVAS.y1);
window.drawLine(the_style,OBJ.verts[to_draw.vert2].x+CANVAS.x1,OBJ.verts[to_draw.vert2].y+CANVAS.y1,OBJ.verts[to_draw.vert3].x+CANVAS.x1,OBJ.verts[to_draw.vert3].y+CANVAS.y1);
window.drawLine(the_style,OBJ.verts[to_draw.vert3].x+CANVAS.x1,OBJ.verts[to_draw.vert3].y+CANVAS.y1,OBJ.verts[to_draw.vert1].x+CANVAS.x1,OBJ.verts[to_draw.vert1].y+CANVAS.y1);
}
void draw_vert(const vector<vert> &verts){
for(int i = 0; i < verts.size();i++) {
draw_vert(verts[i],VERT_STYLE);
}
}
void draw_vert(const vert &to_draw, const Style &the_style) {
window.drawCircleFilled(the_style,to_draw.x+CANVAS.x1,to_draw.y+CANVAS.y1,4);
}
void handle_buttons(const MouseEvent &m_event){
if(LOAD_2D_BTN.visable) if(clicked(LOAD_2D_BTN,m_event)) PROG_MODE = LOAD_2D;
if(WIDTH_BTN.visable) if(clicked(WIDTH_BTN,m_event)) PROG_MODE = WIDTH;
if(SAVE_BTN.visable) if(clicked(SAVE_BTN,m_event)) PROG_MODE = SAVE;
if(EXIT_BTN.visable) if(clicked(EXIT_BTN,m_event)) PROG_MODE = EXIT;
if(ADD_VERTS_BTN.visable) if(clicked(ADD_VERTS_BTN,m_event)) {
//Clear the IO window
clear(IO_WINDOW);
//print the action title
output("Add Verticies.",1);
PROG_MODE = ADD_VERTS;
}
if(ADD_FACES_BTN.visable) if(clicked(ADD_FACES_BTN,m_event)) {
//Clear the IO window
clear(IO_WINDOW);
//print the action title
output("Add Faces.",1);
PROG_MODE = ADD_FACES;
}
if(ADD_EDGES_BTN.visable) if(clicked(ADD_EDGES_BTN,m_event)) {
//Clear the IO window
clear(IO_WINDOW);
//print the action title
output("Add Edges.",1);
PROG_MODE = ADD_EDGES;
}
}
void activate(menu_button &to_activate) {
//deactivate
FILE_BTN.active = false; if(FILE_BTN.enabled) window.drawRectangleOutline(ENABLED,FILE_BTN.my_rect.x1,FILE_BTN.my_rect.y1,FILE_BTN.my_rect.x2,FILE_BTN.my_rect.y2); else window.drawRectangleOutline(DISABLED,FILE_BTN.my_rect.x1,FILE_BTN.my_rect.y1,FILE_BTN.my_rect.x2,FILE_BTN.my_rect.y2);
ADD_BTN.active = false; if(ADD_BTN.enabled) window.drawRectangleOutline(ENABLED,ADD_BTN.my_rect.x1,ADD_BTN.my_rect.y1,ADD_BTN.my_rect.x2,ADD_BTN.my_rect.y2); else window.drawRectangleOutline(DISABLED,ADD_BTN.my_rect.x1,ADD_BTN.my_rect.y1,ADD_BTN.my_rect.x2,ADD_BTN.my_rect.y2);
MOD_BTN.active = false; if(MOD_BTN.enabled) window.drawRectangleOutline(ENABLED,MOD_BTN.my_rect.x1,MOD_BTN.my_rect.y1,MOD_BTN.my_rect.x2,MOD_BTN.my_rect.y2); else window.drawRectangleOutline(DISABLED,MOD_BTN.my_rect.x1,MOD_BTN.my_rect.y1,MOD_BTN.my_rect.x2,MOD_BTN.my_rect.y2);
DEL_BTN.active = false; if(DEL_BTN.enabled) window.drawRectangleOutline(ENABLED,DEL_BTN.my_rect.x1,DEL_BTN.my_rect.y1,DEL_BTN.my_rect.x2,DEL_BTN.my_rect.y2); else window.drawRectangleOutline(DISABLED,DEL_BTN.my_rect.x1,DEL_BTN.my_rect.y1,DEL_BTN.my_rect.x2,DEL_BTN.my_rect.y2);
COLORS_BTN.active = false; if(COLORS_BTN.enabled) window.drawRectangleOutline(ENABLED,COLORS_BTN.my_rect.x1,COLORS_BTN.my_rect.y1,COLORS_BTN.my_rect.x2,COLORS_BTN.my_rect.y2); else window.drawRectangleOutline(DISABLED,COLORS_BTN.my_rect.x1,COLORS_BTN.my_rect.y1,COLORS_BTN.my_rect.x2,COLORS_BTN.my_rect.y2);
//activate
to_activate.active = true; window.drawRectangleOutline(ACTIVE,to_activate.my_rect.x1,to_activate.my_rect.y1,to_activate.my_rect.x2,to_activate.my_rect.y2);
if(FILE_BTN.active) {
LOAD_2D_BTN.visable = true; WIDTH_BTN.visable = true; SAVE_BTN.visable = true; EXIT_BTN.visable = true;
LOAD_2D_BTN.enabled = true; WIDTH_BTN.enabled = true; SAVE_BTN.enabled = true; EXIT_BTN.enabled = true;
}
else {
LOAD_2D_BTN.visable = false; WIDTH_BTN.visable = false; SAVE_BTN.visable = false; EXIT_BTN.visable = false;
LOAD_2D_BTN.enabled = false; WIDTH_BTN.enabled = false; SAVE_BTN.enabled = false; EXIT_BTN.enabled = false;
}
if(ADD_BTN.active) {
ADD_VERTS_BTN.visable = true; ADD_FACES_BTN.visable = true; ADD_EDGES_BTN.visable = true;
ADD_VERTS_BTN.enabled = true; ADD_FACES_BTN.enabled = true; ADD_EDGES_BTN.enabled = true;
}
else {
ADD_VERTS_BTN.visable = false; ADD_FACES_BTN.visable = false; ADD_EDGES_BTN.visable = false;
ADD_VERTS_BTN.enabled = false; ADD_FACES_BTN.enabled = false; ADD_EDGES_BTN.enabled = false;
}
}
void handle_menus(const MouseEvent &m_event) {
if(clicked(FILE_BTN,m_event)) {
//cout << "You Clicked FILE!" << endl;
window.drawImage(FILE_IMAGE,MENU_RECT.x1,MENU_RECT.y1);
activate(FILE_BTN);
char width_str[20];
_ultoa(OBJ.width,width_str,10);
window.drawText(FORE_FONT_STYLE,FONT,WIDTH_BTN.my_rect.x1+70,WIDTH_BTN.my_rect.y1+15,width_str);
}
if(clicked(ADD_BTN,m_event)) {
//cout << "You Clicked ADD!" << endl;
window.drawImage(ADD_DEL_COLORS_IMAGE,MENU_RECT.x1,MENU_RECT.y1);
activate(ADD_BTN);
}
if(clicked(MOD_BTN,m_event)) {
//cout << "You Clicked MOD!" << endl;
window.drawImage(MOD_IMAGE,MENU_RECT.x1,MENU_RECT.y1);
activate(MOD_BTN);
}
if(clicked(DEL_BTN,m_event)) {
//cout << "You Clicked DEL!" << endl;
window.drawImage(ADD_DEL_COLORS_IMAGE,MENU_RECT.x1,MENU_RECT.y1);
activate(DEL_BTN);
}
if(clicked(COLORS_BTN,m_event)) {
//cout << "You Clicked COLORS!" << endl;
window.drawImage(ADD_DEL_COLORS_IMAGE,MENU_RECT.x1,MENU_RECT.y1);
activate(COLORS_BTN);
}
}
bool clicked(const rect &to_check,const MouseEvent &m_event){
//m_event = window.waitForMouseEvent();
int m_x, m_y;
bool click;
m_x = window.getMouseX();
m_y = window.getMouseY();
click = m_event == MouseEvent(MouseEvent::BUTTON_DOWN_EVENT,MouseEvent::LEFT_BUTTON);
//cout << m_event << '\t' << click << endl;
return (click && m_x >= to_check.x1 && m_x <= to_check.x2 && m_y >= to_check.y1 && m_y <= to_check.y2);
}
bool clicked(menu_button &to_check,const MouseEvent &m_event){
int m_x, m_y;
bool click;
m_x = window.getMouseX();
m_y = window.getMouseY();
click = m_event == MouseEvent(MouseEvent::BUTTON_DOWN_EVENT,MouseEvent::LEFT_BUTTON);
//debug output
//cout << m_event << '\t' << click << endl;
if(to_check.enabled && m_x >= to_check.my_rect.x1 && m_x <= to_check.my_rect.x2 && m_y >= to_check.my_rect.y1 && m_y <= to_check.my_rect.y2){
//Draw "hover" rectangle around Load2dButton
if(!to_check.active) window.drawRectangleOutline(HOVER,to_check.my_rect.x1,to_check.my_rect.y1,to_check.my_rect.x2,to_check.my_rect.y2);
if(click) return true;
}
else {
if(to_check.enabled) {
//Draw "enabled" rectangle around Load2dButton
if(!to_check.active) window.drawRectangleOutline(ENABLED,to_check.my_rect.x1,to_check.my_rect.y1,to_check.my_rect.x2,to_check.my_rect.y2);
}
else {
//Draw "disabled" rectangle around Load2dButton
window.drawRectangleOutline(DISABLED,to_check.my_rect.x1,to_check.my_rect.y1,to_check.my_rect.x2,to_check.my_rect.y2);
}
}
return false;
}
bool clicked(button &to_check,const MouseEvent &m_event){
//m_event = window.waitForMouseEvent();
int m_x, m_y;
bool click;
m_x = window.getMouseX();
m_y = window.getMouseY();
click = m_event == MouseEvent(MouseEvent::BUTTON_DOWN_EVENT,MouseEvent::LEFT_BUTTON);
//cout << m_event << '\t' << click << endl;
if(to_check.enabled && m_x >= to_check.my_rect.x1 && m_x <= to_check.my_rect.x2 && m_y >= to_check.my_rect.y1 && m_y <= to_check.my_rect.y2){
//Draw "hover" rectangle around Load2dButton
window.drawRectangleOutline(HOVER,to_check.my_rect.x1,to_check.my_rect.y1,to_check.my_rect.x2,to_check.my_rect.y2);
if(click) return true;
}
else {
if(to_check.enabled) {
//Draw "enabled" rectangle around Load2dButton
window.drawRectangleOutline(ENABLED,to_check.my_rect.x1,to_check.my_rect.y1,to_check.my_rect.x2,to_check.my_rect.y2);
}
else {
//Draw "disabled" rectangle around Load2dButton
window.drawRectangleOutline(DISABLED,to_check.my_rect.x1,to_check.my_rect.y1,to_check.my_rect.x2,to_check.my_rect.y2);
}
}
return false;
}
string input_string(int line_number, string prompt){
//Define String to return
string to_return;
int x = IO_WINDOW.x1 + CHAR_WIDTH;
int y = IO_WINDOW.y1 + line_number * (CHAR_HEIGHT+3) + 3;
//Output the Prompt
window.drawText(FORE_FONT_STYLE,FONT,x,y,prompt.c_str());
//get the chars and output them one at a time
window.flushKeyboardQueue();
KeyboardEvent key;
//Draw cursor:
window.drawLine(FORE_CURSOR_STYLE,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length()+CHAR_WIDTH,y,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length() + 2*CHAR_WIDTH,y);
//wait for char
key = window.waitForKeyboardEvent();
//Erase cursor:
window.drawLine(BACK_CURSOR_STYLE,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length()+CHAR_WIDTH,y,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length() + 2*CHAR_WIDTH,y);
//cout << x << endl;
for (int char_num = 0; KeyboardEvent(NamedKey::ENTER) != key; char_num++){
//debug output
//cout << key << endl;
{
int i;
for(i=0;i < 128 && key != KeyboardEvent(char(i)); i++);
//cout << i << endl;
switch (i) {
case 0x80: //overflow - that is a special - left,right,etc.
case 0x08: //backspace //disabled
char_num--;
//Draw cursor:
window.drawLine(FORE_CURSOR_STYLE,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length() + CHAR_WIDTH,y,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length() + 2*CHAR_WIDTH,y);
//Get the next keypress
window.flushKeyboardQueue();
//wait for char
key = window.waitForKeyboardEvent();
//Erase cursor:
window.drawLine(BACK_CURSOR_STYLE,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length() + CHAR_WIDTH,y,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length() + 2*CHAR_WIDTH,y);
/*
char_num--;
window.drawText(back_font_style,MyFont,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length(),y,&to_return[char_num]);
to_return = mid(to_return,0,to_return.length()-1);
//Draw cursor:
window.drawLine(fore_cursor_style,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length()+CHAR_WIDTH,y,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length() + 2*CHAR_WIDTH,y);
//Get the next keypress
window.flushKeyboardQueue();
//wait for char
key = window.waitForKeyboardEvent();
//Erase cursor:
window.drawLine(back_cursor_style,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length()+CHAR_WIDTH,y,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length() + 2*CHAR_WIDTH,y);
*/
break;
default:
//concatenation
to_return += char(i);
//debug outut
//cout << char(i) << "\t" << i << "\t" << char_num << "\t" << to_return << endl;
//char output
window.drawText(FORE_FONT_STYLE,FONT,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length(),y,&to_return[char_num]);
//debug output
//cout << i << endl;
//Draw cursor:
window.drawLine(FORE_CURSOR_STYLE,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length() + CHAR_WIDTH,y,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length() + 2*CHAR_WIDTH,y);
//Get the next keypress
window.flushKeyboardQueue();
//wait for char
key = window.waitForKeyboardEvent();
//Erase cursor:
window.drawLine(BACK_CURSOR_STYLE,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length() + CHAR_WIDTH,y,x + CHAR_WIDTH*prompt.length() + CHAR_WIDTH*to_return.length() + 2*CHAR_WIDTH,y);
break;
};
}
};
//debug return
//to_return = "Test abcdef.";
return to_return;
}
string mid(string mid_of,int pos,int num_char){
string to_return;
for (int i = pos; i < pos + num_char; i++)
to_return += mid_of[i];
return to_return;
}
void WaitNClear()
{
/*//Set position
int x = IO_WINDOW.x1 + CHAR_WIDTH;
int y = IO_WINDOW.y1 + 4 * (CHAR_HEIGHT+3) + 10;*/
//Display Message
string message;
message = "Press any key to continue...";
//window.drawText(FORE_FONT_STYLE,FONT,x,y,message);
output(message,1);
output(message,2);
output(message,3);
output(message,4);
output(message,5);
//Get keypress
window.flushKeyboardQueue();
window.waitForKeyboardEvent();
//Clear screen
clear();
}
void output(string message,int line_number) {
//Set position
int x = IO_WINDOW.x1 + CHAR_WIDTH;
int y = IO_WINDOW.y1 + line_number * (CHAR_HEIGHT+3) + 3;
//Display Message
window.drawText(FORE_FONT_STYLE,FONT,x,y,message);
}
void clear() {
// Draw a rectangle that covers the entire window
window.drawRectangleFilled(Style::WHITE,0, 0, window.getWidth(), window.getHeight());
}
void clear(const rect &to_clear) {
window.drawRectangleFilled(BACK_FONT_STYLE,to_clear.x1,to_clear.y1,to_clear.x2,to_clear.y2);
}