#include "GUI.h" #include "screen.h" #include #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 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] = ""; 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("", 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); } } } }