- First commit to gitea
This commit is contained in:
941
GUI.cpp
Normal file
941
GUI.cpp
Normal file
@@ -0,0 +1,941 @@
|
||||
#include "GUI.h"
|
||||
|
||||
#include "screen.h"
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
#include "GUIDraw.h"
|
||||
#include "font.h"
|
||||
#include "GUIMouse.h"
|
||||
#include "GUIKeyboard.h"
|
||||
#include "GUIViewport.h"
|
||||
#include "Model.h"
|
||||
#include "renderer.h"
|
||||
#include "Editor.h"
|
||||
//#include "GUIDialogs.h"
|
||||
#include "texture.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
const Color winBack{30, 30, 30, 255};
|
||||
const Color panelBack{53, 53, 60, 255};
|
||||
const Color panel3DBack{40, 40, 43, 255};
|
||||
const Color textBoxBack{61, 61, 66, 255};
|
||||
const Color textBoxBorder{76, 77, 81, 255};
|
||||
const Color buttonBack{63, 63, 70, 255};
|
||||
const Color buttonPressed{62, 153, 247, 255};
|
||||
|
||||
namespace GUI
|
||||
{
|
||||
Font* font {nullptr};
|
||||
float viewPos{0};
|
||||
Vector4 viewSize{0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
|
||||
Vector4 viewStack[10];
|
||||
char viewStackPos{0};
|
||||
int focus{-1};
|
||||
int id{0};
|
||||
bool dot{false};
|
||||
bool empty{false};
|
||||
|
||||
bool menuVisible {false};
|
||||
Vector2 menuPos {0, 0};
|
||||
int subMenu{-1};
|
||||
Vector2 subMenuPos {0, 0};
|
||||
|
||||
bool comboBoxVisible {false};
|
||||
|
||||
int selectedViewport {0};
|
||||
bool zoomed {false};
|
||||
|
||||
Color currentColor {0, 0, 0, 255};
|
||||
|
||||
float a = 6.5f;
|
||||
float b = 12.0f;
|
||||
float c = 24.0f;
|
||||
|
||||
void ResetFocus()
|
||||
{
|
||||
focus = -1;
|
||||
dot = false;
|
||||
empty = false;
|
||||
menuVisible = false;
|
||||
}
|
||||
|
||||
void StartSplitV(const float& value)
|
||||
{
|
||||
assert(viewStackPos < 10);
|
||||
|
||||
viewPos = 0;
|
||||
viewStack[viewStackPos] = viewSize;
|
||||
if (value > 0) {
|
||||
viewStack[viewStackPos].w -= (value + 5);
|
||||
viewSize.w = value;
|
||||
} else {
|
||||
viewStack[viewStackPos].w = -value;
|
||||
viewSize.w -= (-value + 5);
|
||||
}
|
||||
viewStack[viewStackPos].y = viewSize.y + viewSize.w + 5;
|
||||
viewStackPos++;
|
||||
}
|
||||
|
||||
void StartSplitH(const float& value)
|
||||
{
|
||||
assert(viewStackPos < 10);
|
||||
|
||||
viewPos = 0;
|
||||
viewStack[viewStackPos] = viewSize;
|
||||
if (value > 0) {
|
||||
viewStack[viewStackPos].z -= (value + 5);
|
||||
viewSize.z = value;
|
||||
} else {
|
||||
viewStack[viewStackPos].z = -value;
|
||||
viewSize.z -= (-value + 5);
|
||||
}
|
||||
viewStack[viewStackPos].x = viewSize.x + viewSize.z + 5;
|
||||
viewStackPos++;
|
||||
}
|
||||
|
||||
void NextSplit()
|
||||
{
|
||||
assert(viewStackPos > 0);
|
||||
viewPos = 0;
|
||||
viewStackPos--;
|
||||
viewSize = viewStack[viewStackPos];
|
||||
}
|
||||
|
||||
void DrawPanel()
|
||||
{
|
||||
viewPos = 0;
|
||||
GUIDraw::FillRect(viewSize, panelBack);
|
||||
viewSize.x += 10;
|
||||
viewSize.y += 10;
|
||||
viewSize.z -= 20;
|
||||
viewSize.w -= 20;
|
||||
}
|
||||
|
||||
void Draw3DPanel(const int index)
|
||||
{
|
||||
if (not menuVisible and GUIMouse::position.inside(viewSize.GetPosition(), viewSize.GetSize())) {
|
||||
selectedViewport = index;
|
||||
if (GUIKeyboard::key == SDLK_z) {
|
||||
GUIKeyboard::key = SDLK_UNKNOWN;
|
||||
zoomed = not zoomed;
|
||||
}
|
||||
}
|
||||
|
||||
const Color color = (index == selectedViewport ? Color(128, 0, 0, 255) : panel3DBack);
|
||||
viewPos = 0;
|
||||
GUIDraw::FillRect(viewSize, color);
|
||||
viewSize.x += 5;
|
||||
viewSize.y += 5;
|
||||
viewSize.z -= 10;
|
||||
viewSize.w -= 10;
|
||||
}
|
||||
|
||||
void DrawTitle(const char* title)
|
||||
{
|
||||
viewPos = 0;
|
||||
GUIDraw::FillRect({viewSize.x, viewSize.y, viewSize.z, 25}, winBack);
|
||||
Vector2 textSize = font->GetSize(title);
|
||||
const float pos = (viewSize.z-5) * 0.5f - textSize.x * 0.5f;
|
||||
|
||||
font->Print(viewSize.x+5+pos, viewSize.y+4, title);
|
||||
|
||||
viewSize.y += 30;
|
||||
viewSize.w -= 30;
|
||||
}
|
||||
|
||||
void DrawCaption(const char* title)
|
||||
{
|
||||
viewPos = 0;
|
||||
font->Print(viewSize.x, viewSize.y, title);
|
||||
|
||||
viewSize.y += 20;
|
||||
viewSize.w -= 20;
|
||||
}
|
||||
|
||||
const bool DrawComboBox(char* text)
|
||||
{
|
||||
bool retVal = false;
|
||||
Vector4 rect {viewPos+viewSize.x, viewSize.y, viewSize.z, 22};
|
||||
Color backColor = textBoxBack;
|
||||
if (text != nullptr and GUIMouse::position.inside(rect.GetPosition(), rect.GetSize())) {
|
||||
if (GUIMouse::buttons[GUIMouse::Button::Left] == GUIMouse::ButtonState::Down) {
|
||||
retVal = true;
|
||||
}
|
||||
backColor = textBoxBorder;
|
||||
}
|
||||
GUIDraw::FillRect(rect, backColor);
|
||||
GUIDraw::DrawRect(rect, textBoxBorder);
|
||||
|
||||
if (text != nullptr) font->Print(viewPos+viewSize.x+5, viewSize.y+2, text, 15);
|
||||
|
||||
viewPos = 0;
|
||||
viewSize.y += 27;
|
||||
viewSize.w -= 27;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void DrawTextBox(char* text)
|
||||
{
|
||||
Vector4 rect {viewPos+viewSize.x, viewSize.y, viewSize.z, 22};
|
||||
Color backColor = textBoxBack;
|
||||
if (text != nullptr and GUIMouse::position.inside(rect.GetPosition(), rect.GetSize())) {
|
||||
if (GUIMouse::buttons[GUIMouse::Button::Left] == GUIMouse::ButtonState::Down) {
|
||||
focus = id;
|
||||
}
|
||||
backColor = textBoxBorder;
|
||||
}
|
||||
GUIDraw::FillRect(rect, backColor);
|
||||
GUIDraw::DrawRect(rect, textBoxBorder);
|
||||
|
||||
if (text != nullptr) {
|
||||
char textColor = 15;
|
||||
if (focus == id) {
|
||||
textColor = 11;
|
||||
if (GUIKeyboard::key >= SDLK_SPACE and GUIKeyboard::key <= SDLK_z) {
|
||||
const size_t len = strlen(text);
|
||||
if (len < 9) {
|
||||
text[len] = GUIKeyboard::key;
|
||||
text[len+1] = '\0';
|
||||
GUIKeyboard::key = SDLK_UNKNOWN;
|
||||
}
|
||||
} else if (GUIKeyboard::key == SDLK_BACKSPACE) {
|
||||
GUIKeyboard::key = SDLK_UNKNOWN;
|
||||
const size_t len = strlen(text);
|
||||
if (len > 0) text[len-1] = '\0';
|
||||
} else if (GUIKeyboard::key == SDLK_RETURN) {
|
||||
GUIKeyboard::key = SDLK_UNKNOWN;
|
||||
ResetFocus();
|
||||
textColor = 15;
|
||||
} else if (GUIKeyboard::key == SDLK_TAB) {
|
||||
GUIKeyboard::key = SDLK_UNKNOWN;
|
||||
focus++;
|
||||
textColor = 15;
|
||||
}
|
||||
if (focus == id) {
|
||||
const Vector2 size = font->GetSize(text);
|
||||
font->Print(size.x+viewPos+viewSize.x+5, viewSize.y+2, "_", textColor);
|
||||
}
|
||||
}
|
||||
font->Print(viewPos+viewSize.x+5, viewSize.y+2, text, textColor);
|
||||
}
|
||||
|
||||
viewPos = 0;
|
||||
viewSize.y += 27;
|
||||
viewSize.w -= 27;
|
||||
id++;
|
||||
}
|
||||
|
||||
void DrawNumTextBox(float* number, const float size)
|
||||
{
|
||||
Vector4 rect {viewPos+viewSize.x, viewSize.y, size, 22};
|
||||
Color backColor = textBoxBack;
|
||||
|
||||
if (number != nullptr and GUIMouse::position.inside(rect.GetPosition(), rect.GetSize())) {
|
||||
if (GUIMouse::buttons[GUIMouse::Button::Left] == GUIMouse::ButtonState::Down) {
|
||||
dot = false;
|
||||
empty = false;
|
||||
focus = id;
|
||||
}
|
||||
backColor = textBoxBorder;
|
||||
}
|
||||
GUIDraw::FillRect(rect, backColor);
|
||||
GUIDraw::DrawRect(rect, textBoxBorder);
|
||||
|
||||
if (number != nullptr) {
|
||||
int i;
|
||||
char s1[20];
|
||||
char* s2;
|
||||
//sprintf(text, "%.f", number);
|
||||
|
||||
sprintf(s1, "%f", *number);
|
||||
s2 = strchr(s1, '.');
|
||||
i = int(s2 - s1);
|
||||
sprintf(s1, "%.*g", (i+2), *number);
|
||||
|
||||
char textColor = 15;
|
||||
if (focus == id) {
|
||||
textColor = 11;
|
||||
if (dot) strcat(s1, ".");
|
||||
if (empty) s1[0] = '\0';
|
||||
const bool dotAlready = (strchr(s1, '.') != nullptr);
|
||||
if (GUIKeyboard::key >= SDLK_0 and GUIKeyboard::key <= SDLK_9) {
|
||||
if (not empty and s1[0] == '0' and not (strlen(s1)>1 and s1[1] == '.' )) s1[0] = '\0';
|
||||
empty = false;
|
||||
const size_t len = strlen(s1);
|
||||
s1[len] = GUIKeyboard::key;
|
||||
s1[len+1] = '\0';
|
||||
GUIKeyboard::key = SDLK_UNKNOWN;
|
||||
} else if (not dotAlready and GUIKeyboard::key == SDLK_PERIOD) {
|
||||
empty = false;
|
||||
const size_t len = strlen(s1);
|
||||
s1[len] = GUIKeyboard::key;
|
||||
s1[len+1] = '\0';
|
||||
GUIKeyboard::key = SDLK_UNKNOWN;
|
||||
} else if (GUIKeyboard::key == SDLK_BACKSPACE) {
|
||||
GUIKeyboard::key = SDLK_UNKNOWN;
|
||||
const size_t len = strlen(s1);
|
||||
if (len == 1) empty = true;
|
||||
s1[len-1] = '\0';
|
||||
} else if (GUIKeyboard::key == SDLK_RIGHT) {
|
||||
GUIKeyboard::key = SDLK_UNKNOWN;
|
||||
(*number)++;
|
||||
sprintf(s1, "%f", *number);
|
||||
s2 = strchr(s1, '.');
|
||||
i = int(s2 - s1);
|
||||
sprintf(s1, "%.*g", (i+2), *number);
|
||||
} else if (GUIKeyboard::key == SDLK_LEFT) {
|
||||
GUIKeyboard::key = SDLK_UNKNOWN;
|
||||
(*number)--;
|
||||
sprintf(s1, "%f", *number);
|
||||
s2 = strchr(s1, '.');
|
||||
i = int(s2 - s1);
|
||||
sprintf(s1, "%.*g", (i+2), *number);
|
||||
} else if (GUIKeyboard::key == SDLK_RETURN) {
|
||||
GUIKeyboard::key = SDLK_UNKNOWN;
|
||||
ResetFocus();
|
||||
textColor = 15;
|
||||
const size_t len = strlen(s1);
|
||||
if (s1[len-1] == '.') s1[len-1] = '\0';
|
||||
} else if (GUIKeyboard::key == SDLK_TAB) {
|
||||
GUIKeyboard::key = SDLK_UNKNOWN;
|
||||
focus++;
|
||||
textColor = 15;
|
||||
const size_t len = strlen(s1);
|
||||
if (s1[len-1] == '.') s1[len-1] = '\0';
|
||||
}
|
||||
if (focus == id) {
|
||||
const size_t len = strlen(s1);
|
||||
dot = (s1[len-1] == '.');
|
||||
*number = atof(s1);
|
||||
|
||||
const Vector2 size = font->GetSize(s1);
|
||||
font->Print(size.x+viewPos+viewSize.x+5, viewSize.y+2, "_", textColor);
|
||||
}
|
||||
}
|
||||
font->Print(viewPos+viewSize.x+5, viewSize.y+2, s1, textColor);
|
||||
}
|
||||
|
||||
int numElements = viewSize.z / size;
|
||||
float separation = (viewSize.z - (size*numElements)) / (numElements-1);
|
||||
viewPos += size+separation;
|
||||
|
||||
if (viewPos > viewSize.z) {
|
||||
viewPos = 0;
|
||||
viewSize.y += 27;
|
||||
viewSize.w -= 27;
|
||||
}
|
||||
id++;
|
||||
}
|
||||
|
||||
void DrawViewport(const int index)
|
||||
{
|
||||
glViewport(viewSize.x, SCREEN_HEIGHT-(viewSize.y+viewSize.w), viewSize.z, viewSize.w);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(viewSize.x, SCREEN_HEIGHT-(viewSize.y+viewSize.w), viewSize.z, viewSize.w);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
float zoom = viewports[index].zoom;
|
||||
if (zoom < 0) zoom = 1.0f/-zoom;
|
||||
const float x = (viewSize.z * 0.5f) / zoom;
|
||||
const float y = (viewSize.w * 0.5f) / zoom;
|
||||
glOrtho(-x, x, y, -y, 1000, -1000);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glTranslatef(viewports[index].offset.x, viewports[index].offset.y, 0);
|
||||
glRotatef(viewports[index].rotation.x, 1, 0, 0);
|
||||
glRotatef(viewports[index].rotation.y, 0, 1, 0);
|
||||
|
||||
|
||||
if (not menuVisible and GUIMouse::position.inside(viewSize.GetPosition(), viewSize.GetSize())) {
|
||||
if (GUIMouse::buttons[GUIMouse::Button::Right] == GUIMouse::ButtonState::Down) {
|
||||
menuVisible = true;
|
||||
menuPos = GUIMouse::position;
|
||||
}
|
||||
if (not GUIKeyboard::alt and GUIMouse::buttons[GUIMouse::Button::Left] == GUIMouse::ButtonState::Down) {
|
||||
if (Editor::state == Editor::State::None) {
|
||||
if (Editor::mode == Editor::Mode::Paint) {
|
||||
if (viewports[index].renderMode == Viewport::RenderMode::UV) {
|
||||
Renderer::SetState(RENDER_FILL);
|
||||
Color color = model.PickPixel(GUIMouse::position.x, GUIMouse::position.y);
|
||||
Editor::bitmap[(color.x*4)+color.y*128] = currentColor.r;
|
||||
Editor::bitmap[(color.x*4)+1+color.y*128] = currentColor.g;
|
||||
Editor::bitmap[(color.x*4)+2+color.y*128] = currentColor.b;
|
||||
Editor::bitmap[(color.x*4)+3+color.y*128] = currentColor.a;
|
||||
Texture::Update(Editor::texture, 32, 32, Editor::bitmap);
|
||||
|
||||
} else {
|
||||
Renderer::SetState(RENDER_DEPTH | RENDER_FILL);
|
||||
Color color = model.PickPaint(GUIMouse::position.x, GUIMouse::position.y);
|
||||
Editor::bitmap[(color.y*4)+color.z*128] = currentColor.r;
|
||||
Editor::bitmap[(color.y*4)+1+color.z*128] = currentColor.g;
|
||||
Editor::bitmap[(color.y*4)+2+color.z*128] = currentColor.b;
|
||||
Editor::bitmap[(color.y*4)+3+color.z*128] = currentColor.a;
|
||||
Texture::Update(Editor::texture, 32, 32, Editor::bitmap);
|
||||
}
|
||||
} else {
|
||||
Renderer::SetState(RENDER_DEPTH | RENDER_FILL);
|
||||
Color color = model.Pick(GUIMouse::position.x, GUIMouse::position.y);
|
||||
if (Editor::mode == Editor::Mode::Cube) {
|
||||
model.SelectCube(color.r, GUIKeyboard::shift);
|
||||
} else if (Editor::mode == Editor::Mode::Face) {
|
||||
model.SelectFace(color.r, color.g, GUIKeyboard::shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
ResetFocus();
|
||||
}
|
||||
if (GUIMouse::delta.x != 0 or GUIMouse::delta.y != 0) {
|
||||
if (GUIKeyboard::alt or GUIMouse::buttons[GUIMouse::Button::Middle] == GUIMouse::ButtonState::Pressed) {
|
||||
if (GUIKeyboard::shift) {
|
||||
viewports[index].offset += GUIMouse::delta / viewports[index].zoom;
|
||||
} else {
|
||||
viewports[index].rotation += Vector2(GUIMouse::delta.y, -GUIMouse::delta.x)*1;
|
||||
if (viewports[index].rotation.x < -90) viewports[index].rotation.x = -90;
|
||||
if (viewports[index].rotation.x > 90) viewports[index].rotation.x = 90;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (GUIMouse::wheel.x != 0 or GUIMouse::wheel.y != 0) {
|
||||
if (GUIKeyboard::shift) {
|
||||
viewports[index].offset += GUIMouse::wheel / viewports[index].zoom;
|
||||
} else {
|
||||
viewports[index].zoom -= GUIMouse::wheel.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glClearColor(float(panel3DBack.r)/255.0f, float(panel3DBack.g)/255.0f, float(panel3DBack.b)/255.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
if (viewports[index].renderMode == Viewport::RenderMode::Solid) {
|
||||
Renderer::SetState(RENDER_DEPTH | RENDER_FILL);
|
||||
if (viewports[index].light) Renderer::Light(ON);
|
||||
model.DrawSolid();
|
||||
} else if (viewports[index].renderMode == Viewport::RenderMode::Textured) {
|
||||
Renderer::SetState(RENDER_DEPTH | RENDER_FILL | RENDER_TEXTURE);
|
||||
if (viewports[index].light) Renderer::Light(ON);
|
||||
glBindTexture(GL_TEXTURE_2D, Editor::texture);
|
||||
model.DrawSolid();
|
||||
} else if (viewports[index].renderMode == Viewport::RenderMode::Wire) {
|
||||
Renderer::SetState(RENDER_DEPTH);
|
||||
model.DrawWire();
|
||||
} else if (viewports[index].renderMode == Viewport::RenderMode::UV) {
|
||||
Renderer::SetState(RENDER_FILL | RENDER_TEXTURE);
|
||||
glBindTexture(GL_TEXTURE_2D, Editor::texture);
|
||||
model.DrawUV();
|
||||
}
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
}
|
||||
|
||||
const bool DrawButton(const char* text, const SDL_Keycode key, const bool state, const float size = 85)
|
||||
{
|
||||
Vector4 rect {viewPos+viewSize.x, viewSize.y, size, 22};
|
||||
Color backColor = buttonBack;
|
||||
Color borders[4] = {textBoxBorder, winBack, winBack, textBoxBorder};
|
||||
bool retVal {false};
|
||||
ivec2 textPadding {5,2};
|
||||
|
||||
if (state) {
|
||||
backColor = textBoxBorder;
|
||||
borders[0] = borders[3] = winBack;
|
||||
borders[1] = borders[2] = textBoxBorder;
|
||||
textPadding += {1,1};
|
||||
}
|
||||
|
||||
if (GUIMouse::position.inside(rect.GetPosition(), rect.GetSize())) {
|
||||
if (GUIMouse::buttons[GUIMouse::Button::Left] == GUIMouse::ButtonState::Pressed) {
|
||||
borders[0] = borders[3] = winBack;
|
||||
borders[1] = borders[2] = textBoxBorder;
|
||||
textPadding += {1,1};
|
||||
}
|
||||
if (GUIMouse::buttons[GUIMouse::Button::Left] == GUIMouse::ButtonState::Up) {
|
||||
borders[0] = borders[3] = winBack;
|
||||
borders[1] = borders[2] = textBoxBorder;
|
||||
textPadding += {1,1};
|
||||
ResetFocus();
|
||||
retVal = true;
|
||||
}
|
||||
backColor = textBoxBorder;
|
||||
}
|
||||
if (focus == -1 and key != SDLK_UNKNOWN and GUIKeyboard::key == key) {
|
||||
ResetFocus();
|
||||
retVal = true;
|
||||
}
|
||||
|
||||
GUIDraw::FillRect({viewPos+viewSize.x, viewSize.y, size, 22}, backColor);
|
||||
GUIDraw::DrawRect({viewPos+viewSize.x, viewSize.y, size, 22}, borders);
|
||||
font->Print(viewPos+viewSize.x+textPadding.x, viewSize.y+textPadding.y, text, 15);
|
||||
|
||||
int numElements = viewSize.z / size;
|
||||
float separation = (viewSize.z - (size*numElements)) / (numElements-1);
|
||||
viewPos += size+separation;
|
||||
|
||||
if (viewPos > viewSize.z) {
|
||||
viewPos = 0;
|
||||
viewSize.y += 27;
|
||||
viewSize.w -= 27;
|
||||
}
|
||||
//id++;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void DrawStaticTextBox(const char* text, const float size = 85)
|
||||
{
|
||||
Vector4 rect {viewPos+viewSize.x, viewSize.y, size, 22};
|
||||
GUIDraw::FillRect(rect, textBoxBack);
|
||||
GUIDraw::DrawRect(rect, textBoxBorder);
|
||||
font->Print(viewPos+viewSize.x+5, viewSize.y+2, text, 7);
|
||||
|
||||
viewPos += size+10;
|
||||
|
||||
if (viewPos > viewSize.z) {
|
||||
viewPos = 0;
|
||||
viewSize.y += 27;
|
||||
viewSize.w -= 27;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSpace(const int space)
|
||||
{
|
||||
viewPos = 0;
|
||||
viewSize.y += space;
|
||||
viewSize.w -= space;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (font == nullptr) {
|
||||
font = new Font();
|
||||
font->Load("font");
|
||||
}
|
||||
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 100, -100);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
viewStackPos = 0;
|
||||
viewPos = 0;
|
||||
viewSize = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
|
||||
id = 0;
|
||||
}
|
||||
|
||||
void DrawMenu(const int numItems, const float size)
|
||||
{
|
||||
viewSize = Vector4(menuPos.x, menuPos.y, size, 25*numItems);
|
||||
if (menuPos.x+size > SCREEN_WIDTH) viewSize.x = SCREEN_WIDTH - size;
|
||||
if (menuPos.y+25*numItems > SCREEN_HEIGHT) viewSize.y = SCREEN_HEIGHT - 25*numItems;
|
||||
|
||||
GUIDraw::FillRect(viewSize, panelBack);
|
||||
GUIDraw::DrawRect(viewSize, winBack);
|
||||
if (GUIMouse::buttons[GUIMouse::Button::Left] == GUIMouse::ButtonState::Down) {
|
||||
if (not GUIMouse::position.inside(viewSize.GetPosition(), viewSize.GetSize())) {
|
||||
ResetFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSubMenu(const int numItems, const float size)
|
||||
{
|
||||
viewSize = Vector4(subMenuPos.x, subMenuPos.y, size, 25*numItems);
|
||||
if (subMenuPos.x+size > SCREEN_WIDTH) viewSize.x = subMenuPos.x - (size*2);
|
||||
if (subMenuPos.y+25*numItems > SCREEN_HEIGHT) viewSize.y = SCREEN_HEIGHT - 25*numItems;
|
||||
|
||||
GUIDraw::FillRect(viewSize, panelBack);
|
||||
GUIDraw::DrawRect(viewSize, winBack);
|
||||
if (GUIMouse::buttons[GUIMouse::Button::Left] == GUIMouse::ButtonState::Down) {
|
||||
if (not GUIMouse::position.inside(viewSize.GetPosition(), viewSize.GetSize())) {
|
||||
ResetFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bool DrawMenuItem(const char* text, const bool state)
|
||||
{
|
||||
bool retVal = false;
|
||||
Vector4 rect {viewSize.x, viewSize.y, viewSize.z, 25};
|
||||
if (GUIMouse::position.inside(rect.GetPosition(), rect.GetSize())) {
|
||||
subMenu = -1;
|
||||
GUIDraw::FillRect(rect, textBoxBack);
|
||||
if (GUIMouse::buttons[GUIMouse::Button::Left] == GUIMouse::ButtonState::Down) {
|
||||
retVal = true;
|
||||
menuVisible = false;
|
||||
comboBoxVisible = false;
|
||||
}
|
||||
}
|
||||
if (state) font->Print(viewSize.x+3, viewSize.y+2, "+", 15);
|
||||
font->Print(viewSize.x+13, viewSize.y+2, text, 15);
|
||||
|
||||
viewSize.y += 25;
|
||||
viewSize.w -= 25;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void DrawMenuSubItem(const char* text, const int subMenuIndex)
|
||||
{
|
||||
Vector4 rect {viewSize.x, viewSize.y, viewSize.z, 25};
|
||||
if (GUIMouse::position.inside(rect.GetPosition(), rect.GetSize())) {
|
||||
GUIDraw::FillRect(rect, textBoxBack);
|
||||
subMenu = subMenuIndex;
|
||||
subMenuPos = Vector2(viewSize.x+viewSize.z, viewSize.y);
|
||||
} else if (subMenu == subMenuIndex) {
|
||||
GUIDraw::FillRect(rect, textBoxBack);
|
||||
}
|
||||
|
||||
font->Print(viewSize.x+viewSize.z-13, viewSize.y+2, ">", 15);
|
||||
font->Print(viewSize.x+13, viewSize.y+2, text, 15);
|
||||
|
||||
viewSize.y += 25;
|
||||
viewSize.w -= 25;
|
||||
}
|
||||
|
||||
const bool DrawSubMenuItem(const char* text, const bool state)
|
||||
{
|
||||
bool retVal = false;
|
||||
Vector4 rect {viewSize.x, viewSize.y, viewSize.z, 25};
|
||||
if (GUIMouse::position.inside(rect.GetPosition(), rect.GetSize())) {
|
||||
GUIDraw::FillRect(rect, textBoxBack);
|
||||
if (GUIMouse::buttons[GUIMouse::Button::Left] == GUIMouse::ButtonState::Down) {
|
||||
retVal = true;
|
||||
menuVisible = false;
|
||||
}
|
||||
}
|
||||
if (state) font->Print(viewSize.x+3, viewSize.y+2, "+", 15);
|
||||
font->Print(viewSize.x+13, viewSize.y+2, text, 15);
|
||||
|
||||
viewSize.y += 25;
|
||||
viewSize.w -= 25;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
Vector2 GetTransformedAxesUV(const float x, const float y)
|
||||
{
|
||||
Vector2 result {x, y};
|
||||
if (Editor::forcedAxis == 0) result.y = 0;
|
||||
else if (Editor::forcedAxis == 1) result.x = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
Vector3 GetTransformedAxes(const float x, const float y)
|
||||
{
|
||||
Vector3 result {0, 0, 0};
|
||||
|
||||
if (Editor::forcedAxis == 0) {
|
||||
result.x = x + y;
|
||||
result.y = 0;
|
||||
result.z = 0;
|
||||
} else if (Editor::forcedAxis == 1) {
|
||||
result.x = 0;
|
||||
result.y = x + y;
|
||||
result.z = 0;
|
||||
} else if (Editor::forcedAxis == 2) {
|
||||
result.x = 0;
|
||||
result.y = 0;
|
||||
result.z = x + y;
|
||||
} else {
|
||||
float rx = viewports[selectedViewport].rotation.x; while (rx >= 360) rx -= 360; while (rx < 0) rx += 360;
|
||||
float ry = viewports[selectedViewport].rotation.y; while (ry >= 360) ry -= 360; while (ry < 0) ry += 360;
|
||||
if (rx <= 45 or rx >= 315 ) {
|
||||
if (ry <= 45 or ry >= 315) {
|
||||
// x, y
|
||||
result.x = x;
|
||||
result.y = y;
|
||||
} else if (ry > 45 and ry < 135) {
|
||||
// z, y
|
||||
result.z = x;
|
||||
result.y = y;
|
||||
} else if (ry >= 135 and ry < 225) {
|
||||
// -x, y
|
||||
result.x = -x;
|
||||
result.y = y;
|
||||
} else {
|
||||
// -z, y
|
||||
result.z = -x;
|
||||
result.y = y;
|
||||
}
|
||||
} else if (rx > 45 and rx < 180) {
|
||||
if (ry <= 45 or ry >= 315) {
|
||||
// x, -z
|
||||
result.x = x;
|
||||
result.z = -y;
|
||||
} else if (ry > 45 and ry < 135) {
|
||||
// z, x
|
||||
result.z = x;
|
||||
result.x = y;
|
||||
} else if (ry >= 135 and ry < 225) {
|
||||
// -x, z
|
||||
result.x = -x;
|
||||
result.z = y;
|
||||
} else {
|
||||
// -z, -x
|
||||
result.z = -x;
|
||||
result.x = -y;
|
||||
}
|
||||
} else {
|
||||
if (ry <= 45 or ry >= 315) {
|
||||
// x, z
|
||||
result.x = x;
|
||||
result.z = y;
|
||||
} else if (ry > 45 and ry < 135) {
|
||||
// -z, x
|
||||
result.z = x;
|
||||
result.x = -y;
|
||||
} else if (ry >= 135 and ry < 225) {
|
||||
// -x, -z
|
||||
result.x = -x;
|
||||
result.z = -y;
|
||||
} else {
|
||||
// z, -x
|
||||
result.z = -x;
|
||||
result.x = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Draw()
|
||||
{
|
||||
if (Editor::state != Editor::State::None) {
|
||||
if (Editor::mode == Editor::Mode::Face) {
|
||||
if (GUIKeyboard::key == SDLK_x) { Editor::forcedAxis = 0; GUIKeyboard::key = SDLK_UNKNOWN; }
|
||||
if (GUIKeyboard::key == SDLK_y) { Editor::forcedAxis = 1; GUIKeyboard::key = SDLK_UNKNOWN; }
|
||||
if (GUIMouse::slowDelta.x != 0 or GUIMouse::slowDelta.y != 0) {
|
||||
Vector2 axes = GetTransformedAxesUV(GUIMouse::slowDelta.x, GUIMouse::slowDelta.y);
|
||||
if (Editor::state == Editor::State::Grab) model.GrabFaces(axes.x, axes.y);
|
||||
if (Editor::state == Editor::State::Scale) model.ScaleFaces(axes.x, axes.y);
|
||||
}
|
||||
} else if (Editor::mode == Editor::Mode::Cube) {
|
||||
if (GUIKeyboard::key == SDLK_x) { Editor::forcedAxis = 0; GUIKeyboard::key = SDLK_UNKNOWN; }
|
||||
if (GUIKeyboard::key == SDLK_y) { Editor::forcedAxis = 1; GUIKeyboard::key = SDLK_UNKNOWN; }
|
||||
if (GUIKeyboard::key == SDLK_z) { Editor::forcedAxis = 2; GUIKeyboard::key = SDLK_UNKNOWN; }
|
||||
if (GUIMouse::slowDelta.x != 0 or GUIMouse::slowDelta.y != 0) {
|
||||
Vector3 axes = GetTransformedAxes(GUIMouse::slowDelta.x, GUIMouse::slowDelta.y);
|
||||
if (Editor::state == Editor::State::Grab) model.GrabCubes(axes.x, axes.y, axes.z);
|
||||
if (Editor::state == Editor::State::Scale) model.ScaleCubes(axes.x, axes.y, axes.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reset();
|
||||
//model.cubes[0].selected = true;
|
||||
|
||||
StartSplitV(30); //TOOLBAR
|
||||
|
||||
DrawPanel();
|
||||
|
||||
NextSplit();
|
||||
StartSplitV(-30);
|
||||
StartSplitH(200);
|
||||
// INFO PANEL
|
||||
DrawPanel();
|
||||
DrawTitle("State");
|
||||
if (DrawButton("Cubes", SDLK_1, Editor::mode == Editor::Mode::Cube)) Editor::SetMode(Editor::Mode::Cube);
|
||||
if (DrawButton("Faces", SDLK_2, Editor::mode == Editor::Mode::Face)) Editor::SetMode(Editor::Mode::Face);
|
||||
if (DrawButton("Paint", SDLK_3, Editor::mode == Editor::Mode::Paint)) Editor::SetMode(Editor::Mode::Paint);
|
||||
if (DrawButton("Anim", SDLK_4, Editor::mode == Editor::Mode::Anim)) Editor::SetMode(Editor::Mode::Anim);
|
||||
|
||||
DrawSpace(20);
|
||||
if (Editor::mode == Editor::Mode::Cube) {
|
||||
int index = model.GetSelectedCube();
|
||||
DrawTitle("Cube Info");
|
||||
DrawCaption("Name:");
|
||||
DrawTextBox(index != -1 ? model.cubes[index].name : nullptr);
|
||||
|
||||
float* v[9] = {nullptr};
|
||||
if (index != -1) {
|
||||
v[0] = &model.cubes[index].position.x;
|
||||
v[1] = &model.cubes[index].position.y;
|
||||
v[2] = &model.cubes[index].position.z;
|
||||
v[3] = &model.cubes[index].size.x;
|
||||
v[4] = &model.cubes[index].size.y;
|
||||
v[5] = &model.cubes[index].size.z;
|
||||
v[6] = &model.cubes[index].pivot.x;
|
||||
v[7] = &model.cubes[index].pivot.y;
|
||||
v[8] = &model.cubes[index].pivot.z;
|
||||
}
|
||||
DrawCaption("Position:");
|
||||
DrawNumTextBox(v[0], 50);
|
||||
DrawNumTextBox(v[1], 50);
|
||||
DrawNumTextBox(v[2], 50);
|
||||
DrawCaption("Size:");
|
||||
DrawNumTextBox(v[3], 50);
|
||||
DrawNumTextBox(v[4], 50);
|
||||
DrawNumTextBox(v[5], 50);
|
||||
DrawCaption("Pivot:");
|
||||
DrawNumTextBox(v[6], 50);
|
||||
DrawNumTextBox(v[7], 50);
|
||||
DrawNumTextBox(v[8], 50);
|
||||
DrawCaption("Parent:");
|
||||
char parent[10] = "<none>";
|
||||
if (index != -1 and model.cubes[index].parent != -1) strcpy(parent, model.cubes[model.cubes[index].parent].name);
|
||||
if (DrawComboBox(index != -1 ? parent : nullptr)) {
|
||||
comboBoxVisible = not comboBoxVisible;
|
||||
if (comboBoxVisible) {
|
||||
subMenuPos.x = viewSize.z;
|
||||
menuPos = {viewSize.x, viewSize.y};
|
||||
}
|
||||
}
|
||||
|
||||
DrawSpace(20);
|
||||
DrawTitle("Cube Ops");
|
||||
if (DrawButton("New", SDLK_n, false)) model.NewCube();
|
||||
if (DrawButton("Delete", SDLK_BACKSPACE, false)) model.DeleteCube();
|
||||
if (DrawButton("Dup", SDLK_d, false)) {
|
||||
model.DupCube();
|
||||
Editor::SetState(Editor::State::Grab);
|
||||
}
|
||||
if (DrawButton("Grab", SDLK_g, Editor::state == Editor::State::Grab)) Editor::SetState(Editor::State::Grab);
|
||||
if (DrawButton("Scale", SDLK_s, Editor::state == Editor::State::Scale)) Editor::SetState(Editor::State::Scale);
|
||||
if (DrawButton("Pivot", SDLK_p, Editor::state == Editor::State::Pivot)) Editor::SetState(Editor::State::Pivot);
|
||||
|
||||
} else if (Editor::mode == Editor::Mode::Face) {
|
||||
DrawTitle("Face Info");
|
||||
float* v[8] = {nullptr};
|
||||
ivec2 index = model.GetSelectedFace();
|
||||
if (index.x != -1) {
|
||||
v[0] = &model.cubes[index.x].faces[index.y].uv[2].x;
|
||||
v[1] = &model.cubes[index.x].faces[index.y].uv[2].y;
|
||||
v[2] = &model.cubes[index.x].faces[index.y].uv[1].x;
|
||||
v[3] = &model.cubes[index.x].faces[index.y].uv[1].y;
|
||||
v[4] = &model.cubes[index.x].faces[index.y].uv[3].x;
|
||||
v[5] = &model.cubes[index.x].faces[index.y].uv[3].y;
|
||||
v[6] = &model.cubes[index.x].faces[index.y].uv[0].x;
|
||||
v[7] = &model.cubes[index.x].faces[index.y].uv[0].y;
|
||||
}
|
||||
DrawCaption("UV:");
|
||||
DrawNumTextBox(v[0], 42);
|
||||
DrawNumTextBox(v[1], 42);
|
||||
DrawNumTextBox(v[2], 42);
|
||||
DrawNumTextBox(v[3], 42);
|
||||
DrawNumTextBox(v[4], 42);
|
||||
DrawNumTextBox(v[5], 42);
|
||||
DrawNumTextBox(v[6], 42);
|
||||
DrawNumTextBox(v[7], 42);
|
||||
|
||||
DrawSpace(20);
|
||||
DrawTitle("Face Ops");
|
||||
if (DrawButton("Clear", SDLK_c, false)) model.ClearFaces();
|
||||
if (DrawButton("Rotate", SDLK_r, false)) model.RotateFaces();
|
||||
if (DrawButton("FlipH", SDLK_h, false)) model.FlipHFaces();
|
||||
if (DrawButton("FlipV", SDLK_v, false)) model.FlipVFaces();
|
||||
if (DrawButton("Grab", SDLK_g, Editor::state == Editor::State::Grab)) Editor::SetState(Editor::State::Grab);
|
||||
if (DrawButton("Scale", SDLK_s, Editor::state == Editor::State::Scale)) Editor::SetState(Editor::State::Scale);
|
||||
|
||||
}
|
||||
DrawSpace(20);
|
||||
DrawTitle("Texture");
|
||||
char* shortPath = strrchr(Editor::textureFilename, '/')+1;
|
||||
DrawStaticTextBox(shortPath, 145);
|
||||
if (DrawButton("...", SDLK_UNKNOWN, false, 25)) {
|
||||
char oldPath[400];
|
||||
strcpy(oldPath, Editor::textureFilename);
|
||||
const char* path = nullptr;//GUIDialogs::ChooseFile();
|
||||
if (path != nullptr) {
|
||||
strcpy(Editor::textureFilename, path);
|
||||
//free(path);
|
||||
uint8_t* data = Texture::Load(Editor::textureFilename);
|
||||
if (data == nullptr) {
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "File is not a correct PNG!", nullptr);
|
||||
strcpy(Editor::textureFilename, oldPath);
|
||||
} else {
|
||||
memcpy(Editor::bitmap, data, 32*32*4);
|
||||
free(data);
|
||||
Texture::Update(Editor::texture, 32, 32, Editor::bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NextSplit();
|
||||
// 3D VIEWS
|
||||
if (zoomed) {
|
||||
Draw3DPanel(selectedViewport);
|
||||
DrawViewport(selectedViewport);
|
||||
} else {
|
||||
StartSplitH(2.0f*viewSize.z/3.0f);
|
||||
Draw3DPanel(0);
|
||||
DrawViewport(0);
|
||||
NextSplit();
|
||||
StartSplitV(viewSize.w/2.0f);
|
||||
Draw3DPanel(1);
|
||||
DrawViewport(1);
|
||||
NextSplit();
|
||||
Draw3DPanel(2);
|
||||
DrawViewport(2);
|
||||
}
|
||||
NextSplit();
|
||||
// STATUS BAR
|
||||
DrawPanel();
|
||||
|
||||
if (comboBoxVisible) {
|
||||
int numItems = model.numCubes;
|
||||
DrawMenu(numItems, subMenuPos.x);
|
||||
int sel = model.GetSelectedCube();
|
||||
for (int i = 0; i < model.numCubes; i++) {
|
||||
if (i != sel and DrawMenuItem(model.cubes[i].name, model.cubes[sel].parent == i)) model.cubes[sel].parent = i;
|
||||
}
|
||||
if (DrawMenuItem("<none>", model.cubes[sel].parent == -1)) model.cubes[sel].parent = -1;
|
||||
}
|
||||
|
||||
if (menuVisible) {
|
||||
DrawMenu(6, 120);
|
||||
DrawMenuSubItem("Render", 0);
|
||||
DrawMenuSubItem("View", 1);
|
||||
DrawMenuSubItem("Projection", 2);
|
||||
if (DrawMenuItem("Light", viewports[selectedViewport].light)) viewports[selectedViewport].light = not viewports[selectedViewport].light;
|
||||
if (DrawMenuItem("Grid", viewports[selectedViewport].grid)) viewports[selectedViewport].grid = not viewports[selectedViewport].grid;
|
||||
if (DrawMenuItem("Zoomed", zoomed)) zoomed = not zoomed;
|
||||
|
||||
if (subMenu == 0) {
|
||||
DrawSubMenu(4, 120);
|
||||
if (DrawSubMenuItem("Wire", viewports[selectedViewport].renderMode == Viewport::RenderMode::Wire)) viewports[selectedViewport].renderMode = Viewport::RenderMode::Wire;
|
||||
if (DrawSubMenuItem("Solid", viewports[selectedViewport].renderMode == Viewport::RenderMode::Solid)) viewports[selectedViewport].renderMode = Viewport::RenderMode::Solid;
|
||||
if (DrawSubMenuItem("Textured", viewports[selectedViewport].renderMode == Viewport::RenderMode::Textured)) viewports[selectedViewport].renderMode = Viewport::RenderMode::Textured;
|
||||
if (DrawSubMenuItem("UV", viewports[selectedViewport].renderMode == Viewport::RenderMode::UV)) viewports[selectedViewport].renderMode = Viewport::RenderMode::UV;
|
||||
} else if (subMenu == 1) {
|
||||
DrawSubMenu(6, 120);
|
||||
if (DrawSubMenuItem("Front", viewports[selectedViewport].rotation.x == 0 and viewports[selectedViewport].rotation.y == 0)) {
|
||||
viewports[selectedViewport].rotation.x = 0;
|
||||
viewports[selectedViewport].rotation.y = 0;
|
||||
}
|
||||
DrawSubMenuItem("Left", false);
|
||||
DrawSubMenuItem("Top", false);
|
||||
DrawSubMenuItem("Back", false);
|
||||
DrawSubMenuItem("Right", false);
|
||||
DrawSubMenuItem("Bottom", false);
|
||||
} else if (subMenu == 2) {
|
||||
DrawSubMenu(2, 120);
|
||||
DrawSubMenuItem("Orthogonal", true);
|
||||
DrawSubMenuItem("Perspective", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (Editor::state != Editor::State::None) {
|
||||
if (GUIKeyboard::key == SDLK_RETURN) {
|
||||
GUIKeyboard::key = SDLK_UNKNOWN;
|
||||
Editor::SetState(Editor::State::None);
|
||||
}
|
||||
if (GUIMouse::buttons[GUIMouse::Button::Left] == GUIMouse::ButtonState::Down) {
|
||||
Editor::SetState(Editor::State::None);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user