diff --git a/CMakeLists.txt b/CMakeLists.txt index 51038ba..cb86ac9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,7 +47,9 @@ add_executable(Pycron src/main.cpp src/Graphics/PycronImage.h src/Graphics/PycronImage.cpp src/States/Editor/PythonTokenizer.cpp - src/States/Editor/PythonTokenizer.h) + src/States/Editor/PythonTokenizer.h + src/Graphics/Rectangle.cpp + src/Graphics/Rectangle.h) add_subdirectory(dependencies/pocketpy) # Declaring our executable diff --git a/resources/EditorFrame.png b/resources/EditorFrame.png new file mode 100644 index 0000000..5e65cec Binary files /dev/null and b/resources/EditorFrame.png differ diff --git a/resources/GUITest.png b/resources/GUITest.png new file mode 100644 index 0000000..10f7502 Binary files /dev/null and b/resources/GUITest.png differ diff --git a/resources/pico8.png b/resources/pico8.png new file mode 100644 index 0000000..e11dabd Binary files /dev/null and b/resources/pico8.png differ diff --git a/src/Graphics/Rectangle.cpp b/src/Graphics/Rectangle.cpp new file mode 100644 index 0000000..5cf44ae --- /dev/null +++ b/src/Graphics/Rectangle.cpp @@ -0,0 +1,9 @@ +// +// Created by Bobby Lucero on 10/3/24. +// + +#include "Rectangle.h" + +pycron::Rectangle::Rectangle(int x, int y, int width, int height) : x(x), y(y), width(width), height(height){ + +} diff --git a/src/Graphics/Rectangle.h b/src/Graphics/Rectangle.h new file mode 100644 index 0000000..13206a3 --- /dev/null +++ b/src/Graphics/Rectangle.h @@ -0,0 +1,13 @@ +// +// Created by Bobby Lucero on 10/3/24. +// + +#pragma once +namespace pycron{ + class Rectangle { + public: + int x, y; + int width, height; + Rectangle(int x, int y, int width, int height); + }; +} diff --git a/src/States/Editor/EditorState.cpp b/src/States/Editor/EditorState.cpp index 08b162c..3cedbbb 100644 --- a/src/States/Editor/EditorState.cpp +++ b/src/States/Editor/EditorState.cpp @@ -5,10 +5,9 @@ #include #include #include -#include "EditorState.h" -#include "../../Graphics/PycronImage.h" -#include "../../Pycron.h" #include +#include "EditorState.h" + EditorState::EditorState(pkpy::VM *vm, Graphics *graphics) : m_vm(vm), m_graphics(graphics){ @@ -18,6 +17,8 @@ EditorState::EditorState(pkpy::VM *vm, Graphics *graphics) : m_vm(vm), m_graphic std::string randomSource = Pycron::loadFileToString("../python/triangles.py"); + m_editorFrame = m_graphics->loadImage("../resources/EditorFrame.png"); + m_baseBackgroundColor = 56; m_shadowColor = 28; m_baseTextColor = 42; @@ -41,17 +42,31 @@ EditorState::EditorState(pkpy::VM *vm, Graphics *graphics) : m_vm(vm), m_graphic m_cursorX = 0; m_cursorY = 0; + m_charWidth = m_leftLetterSpacing + m_graphics->GetCurrentFontWidth() + m_rightLetterSpacing; // Final size of char with spacing. If the literal width of the font is n, the final width is n + spacing. + m_charHeight = m_topLetterSpacing + m_graphics->GetCurrentFontHeight() + m_bottomLetterSpacing; + + // Hardcoded text editor element positions based on interface graphics + m_textWindowXOffset = 26; + m_textWindowYOffset = 20; + + m_textWindowWidth = 330; + m_textWindowHeight = 168; + + m_textBounds = new pycron::Rectangle(m_textWindowXOffset, m_textWindowYOffset, m_textWindowWidth, m_textWindowHeight); + m_scrollX = 0; m_scrollY = 0; m_cursorBlinkTimer = 0; m_cursorBlinkInterval = 0.5; - m_charWidth = m_leftLetterSpacing + m_graphics->GetCurrentFontWidth() + m_rightLetterSpacing; // Final size of char with spacing. If the literal width of the font is n, the final width is n + spacing. - m_charHeight = m_topLetterSpacing + m_graphics->GetCurrentFontHeight() + m_bottomLetterSpacing; - m_width = (int)(m_graphics->m_screenWidth / m_charWidth); - m_height = (int)(m_graphics->m_screenHeight / m_charHeight); + + std::cout << (int)m_charWidth << "!\n"; + + m_width = (int)(m_textBounds->width / m_charWidth); + std::cout << m_textBounds->width << " : " << (int)m_charWidth << " = " << m_width; + m_height = (int)(m_textBounds->height / m_charHeight); m_characterBuffer = std::vector(m_width * m_height); m_foregroundIndexBuffer = std::vector(m_width * m_height); @@ -69,10 +84,11 @@ EditorState::EditorState(pkpy::VM *vm, Graphics *graphics) : m_vm(vm), m_graphic EditorState::~EditorState() { delete m_pythonTokenizer; + delete m_editorFrame; + delete m_textBounds; } void EditorState::Draw() { - // Set text and color buffers if needed if(m_dirty){ Clear(); @@ -87,12 +103,6 @@ void EditorState::Draw() { if(index > m_text.size() - 1) break; - std::string lineNumber = std::to_string(index); - int size = 2; - int diff = size - (int)lineNumber.size(); - if(diff > 0) lineNumber = std::string(diff, ' ') + lineNumber; - Text(lineNumber, 0, i, i == m_cursorY ? m_lineNumberTextColor : m_commentTextColor, m_lineNumberBackgroundColor); - // Text handling auto tokens = m_pythonTokenizer->tokenizeLine(m_text[index]); @@ -119,43 +129,48 @@ void EditorState::Draw() { }else if(type == TokenType::Unknown){ color = m_baseTextColor; } - Text(tokens[j].value, size + currentPos, i, color, m_baseBackgroundColor); - currentPos += tokens[j].value.size(); + Text(tokens[j].value, currentPos, i, color, m_baseBackgroundColor); + currentPos += (int)tokens[j].value.size(); } } } - m_graphics->Clear(0); + m_graphics->Clear(57); // draw text with info from color buffers for (int i = 0; i < m_characterBuffer.size(); ++i) { - int x = (i % m_width) * m_charWidth; - int y = (i / m_width) * m_charHeight; + int x = (i % m_width) * m_charWidth + m_textBounds->x; + int y = (i / m_width) * m_charHeight + m_textBounds->y; m_graphics->Rect(x, y, m_charWidth, m_charHeight, m_backgroundIndexBuffer[i]); if(m_drawShadows) m_graphics->Char(m_characterBuffer[i], x + m_leftLetterSpacing + 1, y + m_topLetterSpacing + 1, m_shadowColor); m_graphics->Char(m_characterBuffer[i], x + m_leftLetterSpacing, y + m_topLetterSpacing, m_foregroundIndexBuffer[i]); } + // Draw the cursor if(m_cursorVisible) { - int x = (m_cursorX + 2) * m_charWidth; - int y = m_cursorY * m_charHeight; - int index = m_cursorY * m_width + (m_cursorX + 2); + int x = m_cursorX * m_charWidth + m_textBounds->x; + int y = m_cursorY * m_charHeight + m_textBounds->y; + int index = m_cursorY * m_width + m_cursorX; if(m_drawShadows) m_graphics->Rect(x, y, m_charWidth + 1, m_charHeight + 1, m_shadowColor); m_graphics->Rect(x - 1, y - 1, m_charWidth + 1, m_charHeight + 1, m_foregroundIndexBuffer[index]); -// m_graphics->Line(x - 1, y, x - 1, y + m_charHeight - 1, 63); std::string s(1, m_characterBuffer[index]); m_graphics->Text(s, x, y, m_backgroundIndexBuffer[index]); } - // Cursor blink + // Cursor blink timer TODO: probably move to an update function m_cursorBlinkTimer += GetFrameTime(); if(m_cursorBlinkTimer > m_cursorBlinkInterval){ m_cursorVisible = !m_cursorVisible; m_cursorBlinkTimer = 0.0; } + // Editor frame image + m_graphics->Img(m_editorFrame, 0, 0); + + //m_graphics->RectBorder(m_textBounds->x, m_textBounds->y, m_textBounds->width, m_textBounds->height, 23); + } void EditorState::OnEnter() { @@ -170,7 +185,7 @@ void EditorState::OnKeyPressed(int key) { if(key == KEY_LEFT && m_cursorX > 0){ m_cursorX--; } - if(key == KEY_RIGHT && m_cursorX < m_width - 1 - 2){ + if(key == KEY_RIGHT && m_cursorX < m_width - 1){ m_cursorX++; } if(key == KEY_UP){ diff --git a/src/States/Editor/EditorState.h b/src/States/Editor/EditorState.h index ab0b1d3..2a1cebf 100644 --- a/src/States/Editor/EditorState.h +++ b/src/States/Editor/EditorState.h @@ -3,7 +3,9 @@ #include #include "PythonTokenizer.h" #include "../../State.h" - +#include "../../Graphics/PycronImage.h" +#include "../../Pycron.h" +#include "../../Graphics/Rectangle.h" class PycronImage; @@ -24,6 +26,9 @@ private: Graphics* m_graphics; PythonTokenizer* m_pythonTokenizer; + // Editor images + PycronImage* m_editorFrame; + // Size of the character in pixels uint8_t m_charWidth, m_charHeight; @@ -62,6 +67,15 @@ private: float_t m_cursorBlinkTimer; float_t m_cursorBlinkInterval; + + int m_textWindowXOffset; + int m_textWindowYOffset; + + int m_textWindowWidth; + int m_textWindowHeight; + + pycron::Rectangle* m_textBounds; + int m_scrollX; int m_scrollY;