diff --git a/Background.h b/Background.h new file mode 100644 index 0000000..32a12e7 --- /dev/null +++ b/Background.h @@ -0,0 +1,34 @@ +#pragma once + +#include "SFML/Graphics.hpp" + +// =======< MAIN BACKGROUND COLOR >========== + +sf::Color bgColor = sf::Color{ 23, 25, 33 }; + +sf::ConvexShape polygon[6]; + +using namespace sf; + +void Backgroundcolor(sf::RenderWindow &window) { + + polygon[0].setPointCount(10); + polygon[0].setFillColor(bgColor); + polygon[0].setPoint(0, Vector2f(4200, 300)); + polygon[0].setPoint(1, Vector2f(300, -420)); + polygon[0].setPoint(2, Vector2f(-220, 100)); + polygon[0].setPoint(3, Vector2f(120, 1400)); + polygon[0].setPoint(4, Vector2f(-440, 1200)); + polygon[0].setPoint(5, Vector2f(20, 100)); + polygon[0].setPosition(100, 50); + + + + for (int i = 0; i < 6; i++) + { + window.draw(polygon[i]); + } + + window.display(); + +} \ No newline at end of file diff --git a/Content.cpp b/Content.cpp new file mode 100644 index 0000000..f7f53f4 --- /dev/null +++ b/Content.cpp @@ -0,0 +1,326 @@ +#include "Content.h" + +EditorContent::EditorContent(TextDocument& doc) : document(doc) { + this->cursor = Curs::Cursor(0,0); +} + +// TODO : Diferenciar posicion en columnas de chars +// Esta seria posicion en columna? +std::pair EditorContent::cursorPosition() { + int lineN = this->cursor.getLineN(); + int charN = this->cursor.getCharN(); + int column = this->getColumnFromCharN(lineN, charN); + + return std::pair(lineN, column); +} + +void EditorContent::createNewSelection(int anclaLine, int anclaChar) { + this->selections.createNewSelection(anclaLine, anclaChar); +} + +void EditorContent::createNewSelectionFromCursor() { + this->createNewSelection(this->cursor.getLineN(), this->cursor.getCharN()); +} + +void EditorContent::updateLastSelection(int lineN, int charN) { + this->selections.updateLastSelection(lineN, charN); +} + +void EditorContent::removeSelections() { + this->selections.removeSelections(); +} + +bool EditorContent::isSelected(int lineNumber, int charIndexInLine) { + return this->selections.isSelected(lineNumber, charIndexInLine); +} + +SelectionData::Selection EditorContent::getLastSelection() { + return this->selections.getLastSelection(); +} + + +// TODO: Duplicar seleccion en vez de removerla +void EditorContent::duplicateCursorLine() { + this->removeSelections(); + + int lineN = this->cursor.getLineN(); + sf::String lineToAdd = this->document.getLine(lineN); + lineToAdd += '\n'; + this->document.addTextToPos(lineToAdd, lineN + 1, 0); + this->moveCursorDown(); +} + +void EditorContent::swapSelectedLines(bool swapWithUp) { + auto lastSelection = this->getLastSelection(); + // If there is no selection, consider the cursor a selection. Design choice. + if (!lastSelection.activa) { + this->swapCursorLine(swapWithUp); + return; + } + // Range inclusive + int rangeStart = SelectionData::getStartLineN(lastSelection); + int rangeEnd = SelectionData::getEndLineN(lastSelection); + + int startLineN = SelectionData::getStartLineN(lastSelection); + int startCharN = SelectionData::getStartCharN(lastSelection); + int endLineN = SelectionData::getEndLineN(lastSelection); + int endCharN = SelectionData::getEndCharN(lastSelection); + + if (swapWithUp && rangeStart > 0) { + for (int i = rangeStart; i <= rangeEnd; i++) { + this->document.swapLines(i, i - 1); + } + // this->moveCursorUp(document); + this->removeSelections(); + this->createNewSelection(startLineN - 1, startCharN); + this->updateLastSelection(endLineN - 1, endCharN); + + } + else if (!swapWithUp && rangeEnd < this->document.getLineCount() - 1) { + for (int i = rangeEnd; i >= rangeStart; i--) { + this->document.swapLines(i, i + 1); + } + // this->moveCursorDown(document); + this->removeSelections(); + this->createNewSelection(startLineN + 1, startCharN); + this->updateLastSelection(endLineN + 1, endCharN); + } +} + +void EditorContent::swapCursorLine(bool swapWithUp) { + int currentLine = this->cursor.getLineN(); + if (swapWithUp) { + this->document.swapLines(currentLine, std::max(currentLine - 1, 0)); + } + else { + this->document.swapLines(currentLine, std::min(currentLine + 1, this->document.getLineCount() - 1)); + } +} + + +// Actualiza ademas el maximo char alcanzado +bool EditorContent::moveCursorLeft(bool updateActiveSelections) { + bool moved = (this->cursor.getLineN() != 0) + || ((this->cursor.getLineN() == 0) && (this->cursor.getCharN() > 0)); + + if (this->cursor.getCharN() <= 0) { + int newCursorLine = std::max(this->cursor.getLineN() - 1, 0); + int newCursorChar = 0; + if (this->cursor.getLineN() != 0) { + newCursorChar = this->document.charsInLine(newCursorLine); + } + this->cursor.setPosition(newCursorLine, newCursorChar, true); + } + else { + this->cursor.moveLeft(true); + } + + this->handleSelectionOnCursorMovement(updateActiveSelections); + + return moved; +} + +// Actualiza ademas el maximo char alcanzado +void EditorContent::moveCursorRight(bool updateActiveSelections) { + int charsInLine = this->document.charsInLine(this->cursor.getLineN()); + if (this->cursor.getCharN() >= charsInLine) { + int newCursorLine = std::min(this->cursor.getLineN() + 1, this->document.getLineCount() - 1); + // update cursor position only if new line is not same as old, will happen at last line + if (newCursorLine != this->cursor.getLineN()) { + this->cursor.setPosition(newCursorLine, 0, true); + } + } + else { + this->cursor.moveRight(true); + } + + this->handleSelectionOnCursorMovement(updateActiveSelections); +} + +void EditorContent::moveCursorUp(bool updateActiveSelections) { + if (this->cursor.getLineN() > 0) { + int charsInPreviousLine = this->document.charsInLine(this->cursor.getLineN() - 1); + int currentCharPos = this->cursor.getCharN(); + + // Si el caracter actual existe en la linea de arriba, voy solo arriba, sino voy al final de la linea de arriba + if (currentCharPos <= charsInPreviousLine && this->cursor.getMaxCharNReached() <= charsInPreviousLine) { + this->cursor.moveUpToMaxCharN(); + } + else { + this->cursor.setPosition(this->cursor.getLineN() - 1, charsInPreviousLine); + } + } + + this->handleSelectionOnCursorMovement(updateActiveSelections); +} + +void EditorContent::moveCursorDown(bool updateActiveSelections) { + if (this->cursor.getLineN() < this->document.getLineCount() - 1) { + int charsInNextLine = this->document.charsInLine(this->cursor.getLineN() + 1); + int currentCharPos = this->cursor.getCharN(); + + if (currentCharPos <= charsInNextLine && this->cursor.getMaxCharNReached() <= charsInNextLine) { + this->cursor.moveDownToMaxCharN(); + } + else { + this->cursor.setPosition(this->cursor.getLineN() + 1, charsInNextLine); + } + } + + this->handleSelectionOnCursorMovement(updateActiveSelections); +} + +void EditorContent::moveCursorToEnd(bool updateActiveSelections) { + int charsInLine = this->document.charsInLine(this->cursor.getLineN()); + this->cursor.moveToEnd(charsInLine, true); + this->handleSelectionOnCursorMovement(updateActiveSelections); +} + +void EditorContent::moveCursorToStart(bool updateActiveSelections) { + this->cursor.moveToStart(true); + this->handleSelectionOnCursorMovement(updateActiveSelections); +} + + +void EditorContent::deleteTextBeforeCursorPos(int amount) { + int actuallyMoved = 0; + for (int i = 0; i < amount; i++) { + bool moved = this->moveCursorLeft(); + actuallyMoved += moved ? 1 : 0; + } + this->deleteTextAfterCursorPos(actuallyMoved); +} + +void EditorContent::deleteTextAfterCursorPos(int amount) { + int newLineN = this->cursor.getLineN(); + int newCharN = this->cursor.getCharN(); + this->document.removeTextFromPos(amount, newLineN, newCharN); +} + + +void EditorContent::addTextInCursorPos(sf::String text) { + int textSize = text.getSize(); + int lineN = this->cursor.getLineN(); + int charN = this->cursor.getCharN(); + + this->document.addTextToPos(text, lineN, charN); + for (int i = 0; i < textSize; i++) { + this->moveCursorRight(); + } +} + +// Borra el texto contenido en la seleccion y tambien la seleccion en si +// Devuelve true si se borro una seleccion +bool EditorContent::deleteSelections() { + SelectionData::Selection lastSelection = this->getLastSelection(); + this->removeSelections(); + + // Tomar el inicio de lastSelection, calcular el largo y borrar desde el inicio, + if (lastSelection.activa) { + int startLineN = SelectionData::getStartLineN(lastSelection); + int startCharN = SelectionData::getStartCharN(lastSelection); + int endLineN = SelectionData::getEndLineN(lastSelection); + int endCharN = SelectionData::getEndCharN(lastSelection); + + // Muevo el cursor al inicio de la seleccion + this->cursor.setPosition(startLineN, startCharN, true); + + // -1 por como funcionan los extremos de la seleccion + int amount = this->document.charAmountContained(startLineN, startCharN, endLineN, endCharN) - 1; + this->deleteTextAfterCursorPos(amount); + } + + return lastSelection.activa; +} + +sf::String EditorContent::copySelections() { + SelectionData::Selection lastSelection = this->getLastSelection(); + //this->removeSelections(); + + sf::String copied = ""; + // Tomar el inicio de lastSelection, calcular el largo y borrar desde el inicio, + if (lastSelection.activa) { + int startLineN = SelectionData::getStartLineN(lastSelection); + int startCharN = SelectionData::getStartCharN(lastSelection); + int endLineN = SelectionData::getEndLineN(lastSelection); + int endCharN = SelectionData::getEndCharN(lastSelection); + + // Muevo el cursor al inicio de la seleccion + this->cursor.setPosition(startLineN, startCharN, true); + + // -1 por como funcionan los extremos de la seleccion + int amount = this->document.charAmountContained(startLineN, startCharN, endLineN, endCharN) - 1; + copied = this->document.getTextFromPos(amount, startLineN, startCharN); + } + return copied; +} + +void EditorContent::handleSelectionOnCursorMovement(bool updateActiveSelections) { + if (updateActiveSelections) { + this->updateLastSelection(this->cursor.getLineN(), this->cursor.getCharN()); + } + else { + this->removeSelections(); + } +} + +int EditorContent::linesCount() { + return this->document.getLineCount(); +} + +// TODO: cols != chars +int EditorContent::colsInLine(int line) { + return this->document.charsInLine(line); +} + +sf::String EditorContent::getLine(int line) { + return this->document.getLine(line); +} + +sf::String EditorContent::getCursorLine() { + return this->getLine(cursor.getLineN()); +} + +// TODO: column != charN +void EditorContent::resetCursor(int line, int column) { + this->cursor.setPosition(line, column); + this->cursor.setMaxCharNReached(column); +} + +// TODO: Deberia tirar error si no existe la linea +int EditorContent::getCharIndexOfColumn(int lineN, int column) { + sf::String line = this->getLine(lineN); + int len = this->colsInLine(lineN); + int currentCol = 0; + for (int charN = 0; charN < len; charN++) { + + if (column <= currentCol) { + return charN; + } + + if (line[charN] == '\t') { + currentCol += 4; + } + else { + currentCol++; + } + } + return len == 0 ? 0 : len - 1; +} + +// TODO: Refactor es casi igual al otro metodo +int EditorContent::getColumnFromCharN(int lineN, int charN) { + sf::String line = this->getLine(lineN); + int len = this->colsInLine(lineN); // El nombre esta mal, pero devuelve los chars + int currentCol = 0; + for (int charNact = 0; charNact < charN; charNact++) { + if (line[charNact] == '\t') { + currentCol += 4; + } + else { + currentCol++; + } + } + + return currentCol; +} \ No newline at end of file diff --git a/Content.h b/Content.h new file mode 100644 index 0000000..02ce10d --- /dev/null +++ b/Content.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include "Document.h" +#include "Cursor.h" + +#include "SFML/Graphics.hpp" + +class EditorContent { +public: + EditorContent(TextDocument& textDocument); + + void createNewSelection(int anclaLine, int anclaChar); + void createNewSelectionFromCursor(); + void updateLastSelection(int lineN, int charN); + + void removeSelections(); + SelectionData::Selection getLastSelection(); + + void duplicateCursorLine(); + void swapCursorLine(bool swapWithUp); + void swapSelectedLines(bool swapWithUp); + + bool isSelected(int lineNumber, int charIndexInLine); + bool deleteSelections(); + sf::String copySelections(); + + // TODO: Se puede pasar los valores por defecto al .cpp ? + bool moveCursorLeft(bool updateActiveSelections = false); + void moveCursorRight(bool updateActiveSelections = false); + void moveCursorUp(bool updateActiveSelections = false); + void moveCursorDown(bool updateActiveSelections = false); + + void moveCursorToEnd(bool updateActiveSelections = false); + void moveCursorToStart(bool updateActiveSelections = false); + + void addTextInCursorPos(sf::String text); + void deleteTextAfterCursorPos(int amount); + void deleteTextBeforeCursorPos(int amount); + + int linesCount(); + int colsInLine(int line); + sf::String getLine(int line); + sf::String getCursorLine(); + + void resetCursor(int line, int column); + std::pair cursorPosition(); + int getCharIndexOfColumn(int lineN, int column); + int getColumnFromCharN(int lineN, int charN); + +private: + TextDocument& document; + + sf::Font font; + Curs::Cursor cursor; + SelectionData selections; + + void handleSelectionOnCursorMovement(bool updateActiveSelections); + + +}; \ No newline at end of file diff --git a/Cursor.cpp b/Cursor.cpp new file mode 100644 index 0000000..6c0d0cd --- /dev/null +++ b/Cursor.cpp @@ -0,0 +1,88 @@ +#include "Cursor.h" + +Curs::Cursor::Cursor() : Cursor(0, 0){}; + +Curs::Cursor::Cursor(int lineN, int charN) { + this->maxCharNReached = 0; + this->updatePos(lineN, charN); +} + +// updateMaxChar=false por defecto +void Curs::Cursor::setPosition(int lineN, int charN, bool updateMaxChar) { + this->updatePos(lineN, charN); + if (updateMaxChar) { + this->setMaxCharNReached(this->charN); + } +} + +int Curs::Cursor::getLineN() { + return this->lineN; +} + +int Curs::Cursor::getCharN() { + return this->charN; +} + +void Curs::Cursor::setMaxCharNReached(int charN) { + this->maxCharNReached = charN; +} + +int Curs::Cursor::getMaxCharNReached() { + return this->maxCharNReached; +} + +void Curs::Cursor::moveUp() { + this->updatePos(this->lineN - 1, this->charN); +} + +void Curs::Cursor::moveDown() { + this->updatePos(this->lineN + 1, this->charN); +} + +void Curs::Cursor::moveUpToMaxCharN() { + this->updatePos(this->lineN - 1, this->maxCharNReached); +} + +void Curs::Cursor::moveDownToMaxCharN() { + this->updatePos(this->lineN + 1, this->maxCharNReached); +} + +// updateMaxChar=false por defecto +void Curs::Cursor::moveLeft(bool updateMaxChar) { + if (updateMaxChar) { + this->setMaxCharNReached(this->charN - 1); + } + this->updatePos(this->lineN, this->charN - 1); +} + +// updateMaxChar=false por defecto +void Curs::Cursor::moveRight(bool updateMaxChar) { + if (updateMaxChar) { + this->setMaxCharNReached(this->charN + 1); + } + this->updatePos(this->lineN, this->charN + 1); +} + +void Curs::Cursor::moveToEnd(int charsInLine, bool updateMaxChar) { + if (updateMaxChar) { + this->setMaxCharNReached(charsInLine); + } + this->updatePos(this->lineN, charsInLine); +} + +void Curs::Cursor::moveToStart(bool updateMaxChar) { + if (updateMaxChar) { + this->setMaxCharNReached(0); + } + this->updatePos(this->lineN, 0); +} + +void Curs::Cursor::nextLine() { + this->charN = 0; + this->moveDown(); +} + +void Curs::Cursor::updatePos(int l, int c) { + this->lineN = l; + this->charN = c; +} \ No newline at end of file diff --git a/Cursor.h b/Cursor.h new file mode 100644 index 0000000..2909c3c --- /dev/null +++ b/Cursor.h @@ -0,0 +1,39 @@ +#ifndef Cursor_H +#define Cursor_H + +namespace Curs { + class Cursor { + public: + Cursor(); + Cursor(int lineN, int charN); + + void moveUp(); + void moveDown(); + void moveLeft(bool updateMaxChar = false); + void moveRight(bool updateMaxChar = false); + + void moveToEnd(int charsInLine, bool updateMaxChar = false); + void moveToStart(bool updateMaxChar = false); + + void nextLine(); + + int getLineN(); + int getCharN(); + + void setPosition(int lineN, int charN, bool updateMaxChar = false); + + void moveDownToMaxCharN(); + void moveUpToMaxCharN(); + + void setMaxCharNReached(int charN); + int getMaxCharNReached(); + + private: + int lineN, charN; + int maxCharNReached; + + void updatePos(int posY, int posX); + }; +} + +#endif \ No newline at end of file diff --git a/Document.cpp b/Document.cpp new file mode 100644 index 0000000..cc71bfa --- /dev/null +++ b/Document.cpp @@ -0,0 +1,220 @@ +#include "Document.h" + +// La idea es leer el file y guardarlo en buffer (quiero cargarlo en la memoria) +// Para esto uso std::ifstream para levantar el archivo +// TODO: Esto deberia ser el constructot, no quiero llamarlo a mano +bool TextDocument::init(string& filename) { + std::ifstream inputFile(filename); + if (!inputFile.is_open()) { + std::cerr << "Error opening file: " << filename << std::endl; + return false; + } + std::stringstream inputStringStream; + inputStringStream << inputFile.rdbuf(); + + this->buffer = this->toUtf32(inputStringStream.str()); + this->length = buffer.getSize(); // Posiblemente no sea necesario + + inputFile.close(); + this->initLinebuffer(); + return true; +} + +bool TextDocument::saveFile(string& filename) { + std::ofstream outputFile(filename); + if (!outputFile.is_open()) { + std::cerr << "Error opening file: " << filename << std::endl; + return false; + } + + //It looks more straight-forward to me (Luca Errani) + std::stringstream toBeSaved; + for (sf::Uint32 ch : this->buffer) { + toBeSaved << SpecialChars::convertSpecialChar(ch, outputFile); + } + outputFile << toBeSaved.str(); + + outputFile.close(); + + this->documentHasChanged = false; + return true; +} + +bool TextDocument::hasChanged() { + return this->documentHasChanged; +} + +// TODO: Contar newlines mientras leo el archivo en el init +// TODO: Otros sistemas operativos manejan newlines de otras formas (ej \r) +bool TextDocument::initLinebuffer() { + int lineStart = 0; + this->lineBuffer.clear(); + this->lineBuffer.push_back(lineStart); + + int bufferSize = this->buffer.getSize(); + + for (int i = 0; i < bufferSize; i++) { + if (this->buffer[i] == '\n' || this->buffer[i] == 13) { + lineStart = i + 1; + this->lineBuffer.push_back(lineStart); + } + } + return true; +} + +// Devuelve una copia de la linea que esta en mi buffer +sf::String TextDocument::getLine(int lineNumber) { + int lastLine = this->lineBuffer.size() - 1; + + if (lineNumber < 0 || lineNumber > lastLine) { + std::cerr << "lineNumber " << lineNumber << " is not a valid number line. " + << "Max is: " << this->lineBuffer.size() - 1 << std::endl; + return ""; + } + + if (lineNumber == lastLine) { + return this->buffer.substring(this->lineBuffer[lineNumber]); + + } + else { + int bufferStart = this->lineBuffer[lineNumber]; + int nextBufferStart = this->lineBuffer[lineNumber + 1]; // Final no inclusive + int cantidad = nextBufferStart - bufferStart - 1; + + return this->buffer.substring(bufferStart, cantidad); + } +} + +sf::String TextDocument::toUtf32(const std::string& inString) { + sf::String outString = ""; + auto iterEnd = inString.cend(); + + // Decode avanza el iterador + for (auto iter = inString.cbegin(); iter != iterEnd;) { + sf::Uint32 out; + iter = sf::Utf8::decode(iter, iterEnd, out); + outString += out; + } + + return outString; +} + +void TextDocument::addTextToPos(sf::String text, int line, int charN) { + this->documentHasChanged = true; + + int textSize = text.getSize(); + int bufferInsertPos = this->getBufferPos(line, charN); + this->buffer.insert(bufferInsertPos, text); + + int lineAmount = this->lineBuffer.size(); + for (int l = line + 1; l < lineAmount; l++) { + this->lineBuffer[l] += textSize; + } + + for (int i = 0; i < (int)text.getSize(); i++) { + if (text[i] == '\n' || text[i] == 13) { // text[i] == \n + int newLineStart = bufferInsertPos + i + 1; // Nueva linea comienza despues del nuevo \n + + // Inserto O(#lineas) y uso busqueda binaria pues los inicios de lineas son crecientes + this->lineBuffer.insert( + std::lower_bound(this->lineBuffer.begin(), this->lineBuffer.end(), newLineStart), + newLineStart); + } + } +} + +// TODO: Optimizar +void TextDocument::removeTextFromPos(int amount, int lineN, int charN) { + this->documentHasChanged = true; + + int bufferStartPos = this->getBufferPos(lineN, charN); + this->buffer.erase(bufferStartPos, amount); + + // TODO: SUPER OVERKILL. Esto es O(#buffer) y podria ser O(#lineas) + // Revisitar idea de correr los lineBuffers en amount, teniendo en cuenta la cantidad de newlines borradas + this->initLinebuffer(); +} + +sf::String TextDocument::getTextFromPos(int amount, int line, int charN) { + int bufferPos = this->getBufferPos(line, charN); + return this->buffer.substring(bufferPos, amount); +} + +int TextDocument::charAmountContained(int startLineN, int startCharN, int endLineN, int endCharN) { + return this->getBufferPos(endLineN, endCharN) - this->getBufferPos(startLineN, startCharN) + 1; +} + +void TextDocument::swapLines(int lineA, int lineB) { + if (lineA == lineB) { + return; + } + this->documentHasChanged = true; + + int minLine = std::min(lineA, lineB); + int maxLine = std::max(lineA, lineB); + int lastLine = this->getLineCount() - 1; + + if (minLine < 0) { + std::cerr << "SwapLines: Line " << minLine << " does not exist" + << "\n"; + } + if (maxLine > lastLine) { + std::cerr << "SwapLines: Line " << lastLine << " does not exist" + << "\n"; + } + if (minLine == maxLine - 1) { + this->swapWithNextLine(minLine); + } + else { + std::cerr << "Cant swap non-contiguous lines\n"; + } +} + +void TextDocument::swapWithNextLine(int line) { + if (line < 0 || line + 1 == this->getLineCount()) { + std::cerr << "Cant swap with nonexisting line: " << line << "\n"; + } + auto A = this->getLine(line); + auto B = this->getLine(line + 1); + int lenA = A.getSize(); + int lenB = B.getSize(); + + sf::String Z = ""; + Z += B; + Z += '\n'; + Z += A; + + int lineAStart = this->lineBuffer[line]; + + // Counting the \n at the end of A + int totalLen = lenA + 1 + lenB; + + for (int i = 0; i < totalLen; i++) { + this->buffer[i + lineAStart] = Z[i]; + } + this->lineBuffer[line + 1] = this->lineBuffer[line] + lenB + 1; +} + +int TextDocument::getBufferPos(int line, int charN) { + if (line >= (int)this->lineBuffer.size()) { + std::cerr << "\nCan't get buffer pos of: " << line << "\n"; + std::cerr << "Buffer last line is: " << this->lineBuffer.size() - 1 << "\n\n"; + } + return this->lineBuffer[line] + charN; +} + +int TextDocument::charsInLine(int line) const { + // Si es ultima linea, no puedo compararla con inicio de siguiente pues no hay siguiente + int bufferSize = this->lineBuffer.size(); + + if (line == bufferSize - 1) { + return this->buffer.getSize() - this->lineBuffer[this->lineBuffer.size() - 1]; + } + else { + return this->lineBuffer[line + 1] - this->lineBuffer[line] - 1; + } +} + +int TextDocument::getLineCount() const { + return (int)this->lineBuffer.size(); +} \ No newline at end of file diff --git a/Document.h b/Document.h new file mode 100644 index 0000000..258dd47 --- /dev/null +++ b/Document.h @@ -0,0 +1,113 @@ +#pragma once + +#ifndef TextDocument_H +#define TextDocument_H + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "Enumeration.h" + +using std::string; +using std::vector; + +class TextDocument { +public: + bool init(string& filename); + bool saveFile(string& filename); + bool hasChanged(); + + sf::String getLine(int lineNumber); + int charsInLine(int line) const; + int getLineCount() const; + + void addTextToPos(sf::String text, int line, int charN); + void removeTextFromPos(int amount, int line, int charN); + sf::String getTextFromPos(int amount, int line, int charN); + + void swapLines(int lineA, int lineB); + + int charAmountContained(int startLineN, int startCharN, int endLineN, int endCharN); + +private: + bool initLinebuffer(); + sf::String buffer; + int length; + vector lineBuffer; + bool documentHasChanged; + + int getBufferPos(int line, int charN); + + void swapWithNextLine(int line); + + sf::String toUtf32(const std::string& inString); +}; + +#endif + +class SelectionData { +private: + struct Extremo { + Extremo() : lineN(-1), charN(-1) {} + Extremo(int lineN, int charN) : lineN(lineN), charN(charN) {}; + int lineN; + int charN; + + bool operator<(const Extremo& ex) const { + return lineN < ex.lineN || (lineN <= ex.lineN && charN < ex.charN); + } + }; + +public: + SelectionData(); + + struct Selection { + Selection() : activa(false), ancla(), extremo() {} + Selection(int anclaLine, int anclaChar) : activa(false), ancla(anclaLine, anclaChar), extremo() {} + + bool activa; + SelectionData::Extremo ancla; + SelectionData::Extremo extremo; + }; + + void createNewSelection(int anclaLine, int anclaChar); + void updateLastSelection(int extremoLine, int extremoChar); + + void removeSelections(); + bool isSelected(int lineN, int charN) const; + + Selection getLastSelection(); + + // TODO: Para cuando use multiples selecciones con teclado + // util para mover todas x caractes hacia un lado. + // Hay que tener en cuenta el no salirse del documento y cambios de linea, colisiones etc + // TODO: Puede que cada seleccion se necesite mover de a saltos diferentes, + // por ejemplo cuando muevo con ctrl shift de a palabras, esto no serviria en ese caso + // tendria que hacer un "moveSelectionsToNextWord" o algo asi + // TODO: Handlear que pasa cuando las selecciones chocan, ver el merge + void moveSelectionsRight(int charAmount, const TextDocument& doc); + void moveSelectionsLeft(int charAmount, const TextDocument& doc); + + static int getStartLineN(Selection& selection); + static int getStartCharN(Selection& selection); + static int getEndLineN(Selection& selection); + static int getEndCharN(Selection& selection); + +private: + std::vector selections; + int lastSelectionIndex; + + int getLastAnclaLine(); + int getLastAnclaChar(); + int getLastIsActive(); + + bool validIndex(int index); + void removeSelection(int index); +}; \ No newline at end of file diff --git a/Editor.cpp b/Editor.cpp index 8b08aa3..9125dcb 100644 --- a/Editor.cpp +++ b/Editor.cpp @@ -1,63 +1,63 @@ -#include -#include "EditorView.h" -#include "TextDocument.h" -#include "InputController.h" -#include "ImplementationUtils.h" - -int main(int argc, char* argv[]) { - - std::string workingDirectory = ImplementationUtils::getWorkingDirectory(argv[0]); - - std::string saveFileName; - std::string loadFileName; - - if (argc == 2) { - saveFileName = workingDirectory + argv[1]; - loadFileName = workingDirectory + argv[1]; - } else { - saveFileName = workingDirectory + "txt/textoDePruebaGuardado.txt"; - loadFileName = workingDirectory + "txt/textoDePruebaGuardado.txt"; - } - - sf::RenderWindow window(sf::VideoMode(720, 405), "Jonno-text"); - window.setVerticalSyncEnabled(true); - sf::Color backgroundColor = sf::Color(21, 29, 45); - - TextDocument document; - document.init(loadFileName); - - EditorContent editorContent(document); - - EditorView editorView(window, workingDirectory, editorContent); - InputController inputController(editorContent); - - - while (window.isOpen()) { - sf::Event event; - while (window.pollEvent(event)) { - if (event.type == sf::Event::Closed) { - window.close(); - } - if (event.type == sf::Event::Resized) { - editorView.setCameraBounds(event.size.width, event.size.height); - } - if (event.key.code == sf::Keyboard::S && sf::Keyboard::isKeyPressed(sf::Keyboard::LControl)) { - if (document.hasChanged()){ - document.saveFile(saveFileName); - std::cout << "SAVED TO: " << saveFileName << "\n"; - } - } - - inputController.handleEvents(editorView, window, event); - } - - inputController.handleConstantInput(editorView, window); - - window.clear(backgroundColor); - window.setView(editorView.getCameraView()); - editorView.draw(window); - window.display(); - } - - return 0; -} +#include +#include "EditorView.h" +#include "TextDocument.h" +#include "InputController.h" +#include "ImplementationUtils.h" + +int main(int argc, char* argv[]) { + + std::string workingDirectory = ImplementationUtils::getWorkingDirectory(argv[0]); + + std::string saveFileName; + std::string loadFileName; + + if (argc == 2) { + saveFileName = workingDirectory + argv[1]; + loadFileName = workingDirectory + argv[1]; + } else { + saveFileName = workingDirectory + "txt/textoDePruebaGuardado.txt"; + loadFileName = workingDirectory + "txt/textoDePruebaGuardado.txt"; + } + + sf::RenderWindow window(sf::VideoMode(720, 405), "Jonno-text"); + window.setVerticalSyncEnabled(true); + sf::Color backgroundColor = sf::Color(21, 29, 45); + + TextDocument document; + document.init(loadFileName); + + EditorContent editorContent(document); + + EditorView editorView(window, workingDirectory, editorContent); + InputController inputController(editorContent); + + + while (window.isOpen()) { + sf::Event event; + while (window.pollEvent(event)) { + if (event.type == sf::Event::Closed) { + window.close(); + } + if (event.type == sf::Event::Resized) { + editorView.setCameraBounds(event.size.width, event.size.height); + } + if (event.key.code == sf::Keyboard::S && sf::Keyboard::isKeyPressed(sf::Keyboard::LControl)) { + if (document.hasChanged()){ + document.saveFile(saveFileName); + std::cout << "SAVED TO: " << saveFileName << "\n"; + } + } + + inputController.handleEvents(editorView, window, event); + } + + inputController.handleConstantInput(editorView, window); + + window.clear(backgroundColor); + window.setView(editorView.getCameraView()); + editorView.draw(window); + window.display(); + } + + return 0; +} diff --git a/Editor.vcxproj b/Editor.vcxproj new file mode 100644 index 0000000..603856a --- /dev/null +++ b/Editor.vcxproj @@ -0,0 +1,173 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {feec6cad-0238-4d4e-b3cb-7f8e360d5ab8} + Editor + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)\include;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\lib + sfml-system-d.lib;sfml-window-d.lib;sfml-graphics-d.lib;%(AdditionalDependencies) + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + $(SolutionDir)\lib + sfml-system.lib;sfml-window.lib;sfml-graphics.lib;%(AdditionalDependencies) + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)\include;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\lib + sfml-system-d.lib;sfml-window-d.lib;sfml-graphics-d.lib;%(AdditionalDependencies) + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + $(SolutionDir)\lib + sfml-system.lib;sfml-window.lib;sfml-graphics.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Editor.vcxproj.filters b/Editor.vcxproj.filters new file mode 100644 index 0000000..8edce4d --- /dev/null +++ b/Editor.vcxproj.filters @@ -0,0 +1,96 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/Editor.vcxproj.user b/Editor.vcxproj.user new file mode 100644 index 0000000..0f14913 --- /dev/null +++ b/Editor.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/EditorLine.hpp b/EditorLine.hpp new file mode 100644 index 0000000..786cfc7 --- /dev/null +++ b/EditorLine.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include +#include "SFML/Graphics.hpp" + +class EditorLine { + + +private: + std::string content; + static int instances_count; + int line_number = 0; + bool active; + sf::Font* main_font; + sf::Font* content_font; + int size; + float width = 0; + + sf::Color text_color = sf::Color(0, 0, 0); + sf::Color content_color = sf::Color(0, 0, 0); + + sf::Text number_text; + + std::vector line_chars; + + public: + + EditorLine(); + EditorLine(std::string text, sf::Font *font, sf::Font *cotext_font); + + void set_colors(sf::Color text_color, sf::Color content_color); + + sf::Text get_number_text(); + std::vector get_content_chars(); + int get_size(); + std::string get_content(); + float get_width(); + + void insert_char_at(char c, int col); + void delete_char_at(int col); + void insert_word(int col, std::string word); + void delete_word(int start, int end); + std::string break_at(int col); + void merge_with(EditorLine line); + + void set_number(int n); + +private: + sf::Text draw_text(std::string content, int x, bool is_content); + void draw_number(); + void draw_chars(); +}; \ No newline at end of file diff --git a/EditorView.cpp b/EditorView.cpp new file mode 100644 index 0000000..6b915d7 --- /dev/null +++ b/EditorView.cpp @@ -0,0 +1,312 @@ +#include +#include "EditorView.h" + +#include "SFML/Graphics.hpp" + +// TODO: el -50 de la inicializacion de la camara tiene que ver con el marginXoffset +EditorView::EditorView( + const sf::RenderWindow& window, + const sf::String& workingDirectory, + EditorContent& editorContent) + : content(editorContent), + camera(sf::FloatRect(-40, 0, window.getSize().x, window.getSize().y)), + deltaScroll(20), deltaRotation(2), deltaZoomIn(0.8f), deltaZoomOut(1.2f) { + + // this->font.loadFromFile("fonts/FreeMono.ttf"); + this->font.loadFromFile(workingDirectory + "fonts/DejaVuSans-ExtraLight.ttf"); + + this->bottomLimitPx = 1; + this->rightLimitPx = 1; + + this->setFontSize(this->fontSize); // Important to call + + // TODO: Cambiarlo en relacion a la fontsize + this->marginXOffset = 35; + + this->colorMargin = sf::Color(17, 18, 23); + + this->colorChar = sf::Color::White; + this->colorSelection = sf::Color(106, 154, 232); +} + +void EditorView::FontSizeScrollChangeDown() { + if (this->fontSize <= this->MinFontSize) { std::cout << "Min" << std::endl; } + else { + this->fontSize--; + this->setFontSize(this->fontSize); + } +} + +void EditorView::FontSizeScrollChangeUp() { + if (this->fontSize >= this->MaxFontSize) { std::cout << "Max" << std::endl; } + else { + this->fontSize++; + this->setFontSize(this->fontSize); + } +} + +// TODO: Divide fontsize from lineheight +void EditorView::setFontSize(int fontSize) { + this->fontSize = fontSize; + this->lineHeight = fontSize; + + // HACK: Because I use only monospace fonts, every char is the same width + // so I get the width drawing a single character (A WIDE ONE TO BE SURE) + sf::Text tmpText; + tmpText.setFont(this->font); + tmpText.setCharacterSize(this->fontSize); + tmpText.setString("_"); + float textwidth = tmpText.getLocalBounds().width; + this->charWidth = textwidth; +} + +float EditorView::getRightLimitPx() { + return this->rightLimitPx; +} + +float EditorView::getBottomLimitPx() { + return this->bottomLimitPx; +} + +int EditorView::getLineHeight() { + return this->lineHeight; +} + +int EditorView::getCharWidth() { + return this->charWidth; +} +void EditorView::SelectAll() { + for(int Line = 1; Line <= this->content.linesCount(); Line++){ + + int LineCount = this->content.linesCount(); + std::cout << LineCount << std::endl; + + this->content.createNewSelection(LineCount, 10); + + // this->content.moveCursorLeft(true); + // this->content.moveCursorRight(true); + + } + +} + +void EditorView::draw(sf::RenderWindow& window) { + // TODO: El content devuelve un vector diciendo que alto tiene cada linea, + // por ahora asumo que todas miden "1" de alto + this->drawLines(window); + + // Dibujo los numeros de la izquierda + + // TODO: Hacer una clase separada para el margin + for (int lineNumber = 1; lineNumber <= this->content.linesCount(); lineNumber++) { + int lineHeight = 1; + + int blockHeight = lineHeight * this->fontSize; + + sf::Text lineNumberText; + lineNumberText.setFillColor(sf::Color::White); + lineNumberText.setFont(this->font); + lineNumberText.setString(std::to_string(lineNumber)); + lineNumberText.setCharacterSize(this->fontSize - 1); + lineNumberText.setPosition(-this->marginXOffset, blockHeight * (lineNumber - 1)); + + sf::RectangleShape marginRect(sf::Vector2f(this->marginXOffset - 5, blockHeight)); + marginRect.setFillColor(this->colorMargin); + marginRect.setPosition(-this->marginXOffset, blockHeight * (lineNumber - 1)); + + window.draw(marginRect); + window.draw(lineNumberText); + } + + this->drawCursor(window); +} + +// TODO: esto lo deberia manejar el editorContetn de alguna forma? 4 harcodeado +int colsOf(sf::String& currentLineText) { + int cols = 0; + for (char c : currentLineText) { + if (c == '\t') { + cols += 4; + } + else { + cols++; + } + } + return cols; +} + +// TODO: Reemplazar fontSize por fontHeight especifica para cada tipo de font. +// TODO: Multiples cursores similar a Selecciones, que los moveUp.. etc muevan todos +// TODO: Que devuelva un vector diciendo el alto que ocupa el dibujo de cada linea, para saber el tamaño de cada linea en el margen +void EditorView::drawLines(sf::RenderWindow& window) { + this->bottomLimitPx = this->content.linesCount() * this->fontSize; + + for (int lineNumber = 0; lineNumber < this->content.linesCount(); lineNumber++) { + sf::String line = this->content.getLine(lineNumber); + + sf::String currentLineText = ""; + + // TODO: Esto es al pe? + this->rightLimitPx = std::max((int)this->rightLimitPx, (int)(this->charWidth * line.getSize())); + + float offsetx = 0; + bool previousSelected = false; + + for (int charIndexInLine = 0; charIndexInLine <= (int)line.getSize(); charIndexInLine++) { + // En general hay una unica seleccion, en el futuro podria haber mas de una + bool currentSelected = content.isSelected(lineNumber, charIndexInLine); + + // Cuando hay un cambio, dibujo el tipo de seleccion anterior + // Tambien dibujo cuando es el fin de la linea actual + if (currentSelected != previousSelected || charIndexInLine == (int)line.getSize()) { + sf::Text texto; + texto.setFillColor(this->colorChar); + // texto.setFillColor(sf::Color{214,214,24}); + texto.setFont(font); + texto.setString(currentLineText); + texto.setCharacterSize(this->fontSize); + texto.setPosition(offsetx, lineNumber * this->fontSize); + + if (previousSelected) { + int currentColsAmount = colsOf(currentLineText); + sf::RectangleShape selectionRect( + sf::Vector2f(this->charWidth * currentColsAmount, this->fontSize)); + // Selected color + selectionRect.setFillColor(this->colorSelection); + // TODO: Que el +2 no sea un numero magico + selectionRect.setPosition(offsetx, 2 + lineNumber * this->fontSize); + window.draw(selectionRect); + } + + window.draw(texto); + + previousSelected = currentSelected; + offsetx += this->charWidth * colsOf(currentLineText); + currentLineText = ""; + } + + // Voy acumulando la string de la linea actual + currentLineText += line[charIndexInLine]; + } + } +} + + +// TODO: No harcodear constantes aca. CursorView? +void EditorView::drawCursor(sf::RenderWindow& window) { + int offsetY = 2; + int cursorDrawWidth = 2; + + int charWidth = getCharWidth(); + int lineHeight = getLineHeight(); + + std::pair cursorPos = this->content.cursorPosition(); + int lineN = cursorPos.first; + int column = cursorPos.second; + + sf::RectangleShape cursorRect(sf::Vector2f(cursorDrawWidth, lineHeight)); + cursorRect.setFillColor(sf::Color::White); + + cursorRect.setPosition( + column * charWidth, + (lineN * lineHeight) + offsetY); + + window.draw(cursorRect); +} + +// TODO: Esto no considera que los tabs \t existen +// Asume que el x=0 es donde empieza el texto +std::pair EditorView::getDocumentCoords( + float mouseX, float mouseY) { + + int lineN = mouseY / this->getLineHeight(); + int charN = 0; + + // Restrinjo numero de linea a la altura del documento + int lastLine = this->content.linesCount() - 1; + + if (lineN < 0) { + lineN = 0; + charN = 0; + } + else if (lineN > lastLine) { + lineN = lastLine; + charN = this->content.colsInLine(lineN); + } + else { + lineN = std::max(lineN, 0); + lineN = std::min(lineN, lastLine); + + // column != charN because tabs + int column = std::round(mouseX / this->getCharWidth()); + charN = this->content.getCharIndexOfColumn(lineN, column); + + // Restrinjo numero de caracter a cant de caracteres de la linea + charN = std::max(charN, 0); + charN = std::min(charN, this->content.colsInLine(lineN)); + } + + return std::pair(lineN, charN); +} + +void EditorView::scrollUp(sf::RenderWindow& window) { + float height = window.getView().getSize().y; + auto camPos = this->camera.getCenter(); + // Scrolleo arriba solo si no me paso del limite superior + if (camPos.y - height / 2 > 0) { + this->camera.move(0, -this->deltaScroll); + } +} + +void EditorView::scrollDown(sf::RenderWindow& window) { + float height = window.getView().getSize().y; + float bottomLimit = std::max(this->getBottomLimitPx(), height); + auto camPos = this->camera.getCenter(); + // Numero magico 20 como un plus + if (camPos.y + height / 2 < bottomLimit + 20) { + this->camera.move(0, this->deltaScroll); + } +} + +void EditorView::scrollLeft(sf::RenderWindow& window) { + float width = window.getView().getSize().x; + auto camPos = this->camera.getCenter(); + // Scrolleo arriba si no me paso del limite izquierdo + if (camPos.x - width / 2 > -this->marginXOffset) { + this->camera.move(-this->deltaScroll, 0); + } +} + +void EditorView::scrollRight(sf::RenderWindow& window) { + float width = window.getView().getSize().x; + float rightLimit = std::max(this->getRightLimitPx(), width); + auto camPos = this->camera.getCenter(); + // Numero magico 20 como un plus + if (camPos.x + width / 2 < rightLimit + 20) { + this->camera.move(this->deltaScroll, 0); + } +} + +void EditorView::rotateLeft() { + this->camera.rotate(this->deltaRotation); +} + +void EditorView::rotateRight() { + this->camera.rotate(-this->deltaRotation); +} + +void EditorView::zoomIn() { + this->camera.zoom(this->deltaZoomIn); +} + +void EditorView::zoomOut() { + this->camera.zoom(this->deltaZoomOut); +} + +void EditorView::setCameraBounds(int width, int height) { + this->camera = sf::View(sf::FloatRect(-50, 0, width, height)); +} + +sf::View EditorView::getCameraView() { + return this->camera; +} \ No newline at end of file diff --git a/EditorView.h b/EditorView.h new file mode 100644 index 0000000..6ee18f5 --- /dev/null +++ b/EditorView.h @@ -0,0 +1,79 @@ +#pragma once +#include "SFML/Graphics.hpp" +#include "Content.h" +#include + +#define LINE_HEIGHT 30 + + +class EditorView { + public: + EditorView(const sf::RenderWindow& window, + const sf::String& workingDirectory, + EditorContent& editorContent); + + void draw(sf::RenderWindow& window); + void setFontSize(int fontSize); + + void scrollUp(sf::RenderWindow& window); + void scrollDown(sf::RenderWindow& window); + void scrollLeft(sf::RenderWindow& window); + void scrollRight(sf::RenderWindow& window); + void FontSizeScrollChangeDown(); + void FontSizeScrollChangeUp(); + + void scrollTo(float x, float y); + + void rotateLeft(); + void rotateRight(); + + void SelectAll(); + + void zoomIn(); + void zoomOut(); + + int getLineHeight(); + int getCharWidth(); + + float getRightLimitPx(); + float getBottomLimitPx(); + + sf::View getCameraView(); + void setCameraBounds(int width, int height); + + void setDeltaScroll(float delta); + void setDeltaRotation(float delta); + + // TODO: Replace std::pair with coordinates object + std::pair getDocumentCoords(float mouseX, float mouseY); + +private: + EditorContent& content; + + void drawLines(sf::RenderWindow& window); + void drawCursor(sf::RenderWindow& window); + + sf::Font font; + int fontSize = 13; + int marginXOffset; + sf::Color colorMargin; + + int MaxFontSize = 40; + int MinFontSize = 9; + + int lineHeight; + int charWidth; + + float rightLimitPx; + float bottomLimitPx; + + sf::Color colorChar; + sf::Color colorSelection; + + sf::View camera; + float deltaScroll; + float deltaRotation; + float deltaZoomIn, deltaZoomOut; + + +}; \ No newline at end of file diff --git a/Enumaration.cpp b/Enumaration.cpp new file mode 100644 index 0000000..b5342ab --- /dev/null +++ b/Enumaration.cpp @@ -0,0 +1,80 @@ +#include "Enumeration.h" +#include + +namespace SpecialChars { + + std::string convertSpecialChar(sf::Uint32 c, std::ofstream& outputFile) { + switch (c) { + case A_LOWER_ACUTE: + return "a"; + case E_LOWER_ACUTE: + return "é"; + case I_LOWER_ACUTE: + return "í"; + case O_LOWER_ACUTE: + return "ó"; + case U_LOWER_ACUTE: + return "ú"; + case A_LOWER_GRAVE: + return "à"; + case E_LOWER_GRAVE: + return "è"; + case I_LOWER_GRAVE: + return "ì"; + case O_LOWER_GRAVE: + return "ò"; + case U_LOWER_GRAVE: + return "ù"; + case A_LOWER_CIRCUMFLEX: + return "â"; + case E_LOWER_CIRCUMFLEX: + return "ê"; + case I_LOWER_CIRCUMFLEX: + return "î"; + case O_LOWER_CIRCUMFLEX: + return "ô"; + case U_LOWER_CIRCUMFLEX: + return "û"; + case A_UPPER_ACUTE: + return "Á"; + case E_UPPER_ACUTE: + return "É"; + case I_UPPER_ACUTE: + return "Í"; + case O_UPPER_ACUTE: + return "Ó"; + case U_UPPER_ACUTE: + return "Ú"; + case A_UPPER_GRAVE: + return "À"; + case E_UPPER_GRAVE: + return "È"; + case I_UPPER_GRAVE: + return "Ì"; + case O_UPPER_GRAVE: + return "Ò"; + case U_UPPER_GRAVE: + return "Ù"; + case A_UPPER_CIRCUMFLEX: + return "Â"; + case E_UPPER_CIRCUMFLEX: + return "Ê"; + case I_UPPER_CIRCUMFLEX: + return "Î"; + case O_UPPER_CIRCUMFLEX: + return "Ô"; + case U_UPPER_CIRCUMFLEX: + return "Û"; + case N_LOWER_TILDE: + return "ñ"; + } + if (c < 128) { + return sf::String(c); + } + else { + outputFile.close(); + std::cerr << "\nERROR: Can't save character: " << c << std::endl; + } + return ""; + } +} // namespace SpecialChars \ No newline at end of file diff --git a/Enumeration.h b/Enumeration.h new file mode 100644 index 0000000..688b664 --- /dev/null +++ b/Enumeration.h @@ -0,0 +1,54 @@ +#pragma once + +#include +#include "SFML/Graphics.hpp" +#include + +#define A_LOWER_GRAVE 224 +#define A_LOWER_ACUTE 225 +#define A_LOWER_CIRCUMFLEX 226 + +#define E_LOWER_GRAVE 232 +#define E_LOWER_ACUTE 233 +#define E_LOWER_CIRCUMFLEX 234 + +#define I_LOWER_GRAVE 236 +#define I_LOWER_ACUTE 237 +#define I_LOWER_CIRCUMFLEX 238 + +#define N_LOWER_TILDE 241 + +#define O_LOWER_GRAVE 242 +#define O_LOWER_ACUTE 243 +#define O_LOWER_CIRCUMFLEX 244 + +#define U_LOWER_GRAVE 249 +#define U_LOWER_ACUTE 250 +#define U_LOWER_CIRCUMFLEX 251 + +//-----Upper case accents VOWELS------// +#define A_UPPER_GRAVE 192 +#define A_UPPER_ACUTE 193 +#define A_UPPER_CIRCUMFLEX 194 + +#define E_UPPER_GRAVE 200 +#define E_UPPER_ACUTE 201 +#define E_UPPER_CIRCUMFLEX 202 + +#define I_UPPER_GRAVE 204 +#define I_UPPER_ACUTE 205 +#define I_UPPER_CIRCUMFLEX 206 + +#define O_UPPER_GRAVE 210 +#define O_UPPER_ACUTE 211 +#define O_UPPER_CIRCUMFLEX 212 + +#define U_UPPER_GRAVE 217 +#define U_UPPER_ACUTE 218 +#define U_UPPER_CIRCUMFLEX 219 + +namespace SpecialChars { + + std::string convertSpecialChar(sf::Uint32 c, std::ofstream& outputFile); + +} // namespace SpecialChars \ No newline at end of file diff --git a/Filesystem.h b/Filesystem.h new file mode 100644 index 0000000..7cd6170 --- /dev/null +++ b/Filesystem.h @@ -0,0 +1,21 @@ +#pragma once + +#include "SFML/Graphics.hpp" + +sf::Event evt; + +void Openfiledialog(sf::RenderWindow &window) { + /* TODO */ +} + +void Exitfromeditor(sf::RenderWindow& window) { + + // SAVIND BEFORE EXIT + // ..... + // + + if (evt.type == sf::Event::KeyPressed) { + if (evt.key.code == sf::Keyboard::Escape) + window.close(); + } +} \ No newline at end of file diff --git a/Icon.h b/Icon.h new file mode 100644 index 0000000..b862186 --- /dev/null +++ b/Icon.h @@ -0,0 +1,9 @@ +#pragma once + +#include "SFML/Graphics.hpp" + +void SetIcon(sf::RenderWindow& window) { + sf::Image Icon; + Icon.loadFromFile("Icon.png"); + window.setIcon(Icon.getSize().x, Icon.getSize().y, Icon.getPixelsPtr()); +} \ No newline at end of file diff --git a/Input.cpp b/Input.cpp new file mode 100644 index 0000000..962e65e --- /dev/null +++ b/Input.cpp @@ -0,0 +1,263 @@ +#include "Input.h" + +InputController::InputController(EditorContent& editorContent) + : editorContent(editorContent) { + this->mouseDown = false; + this->shiftPressed = false; +} + +void InputController::handleEvents( + EditorView& textView, + sf::RenderWindow& window, + sf::Event& event) { + + this->handleMouseEvents(textView, window, event); + this->handleKeyPressedEvents(textView, event); + this->handleKeyReleasedEvents(event); + this->handleTextEnteredEvent(textView, event); +} + +void InputController::handleConstantInput(EditorView& textView, + sf::RenderWindow& window) { + // Rotating + if (sf::Keyboard::isKeyPressed(sf::Keyboard::LControl)) { + if (sf::Keyboard::isKeyPressed(sf::Keyboard::R)) { + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) { + textView.rotateLeft(); + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) { + textView.rotateRight(); + } + } + } + + // TODO: Esto asume que siempre que esta el mouse presionado se esta seleccionando + // TODO: Ubicar el textview con variables genericas (No magic numbers) + // TODO: No permitir scrollear mas alla del textview + if (this->isMouseDown()) { + auto mousepos = sf::Mouse::getPosition(window); + auto mousepos_text = window.mapPixelToCoords(mousepos); + + updateCursorInEditor(textView, mousepos_text.x, mousepos_text.y); + + float textViewTop = 0; + float textViewBottom = window.getView().getSize().y - 5; + float textViewLeft = 0; + float textViewRight = window.getView().getSize().x; + + if (mousepos.x < textViewLeft) { + textView.scrollLeft(window); + } + else if (mousepos.x > textViewRight) { + textView.scrollRight(window); + } + + if (mousepos.y < textViewTop) { + textView.scrollUp(window); + } + else if (mousepos.y > textViewBottom) { + textView.scrollDown(window); + } + } +} + +void InputController::handleMouseEvents( + EditorView& textView, + sf::RenderWindow& window, + sf::Event& event) { + + if (event.type == sf::Event::MouseWheelScrolled) { + if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel) { + if (event.mouseWheelScroll.delta > 0) { + textView.scrollUp(window); + } + else { + textView.scrollDown(window); + } + } + else if (event.mouseWheelScroll.wheel == sf::Mouse::HorizontalWheel) { + if (event.mouseWheelScroll.delta > 0) { + textView.scrollLeft(window); + } + else { + textView.scrollRight(window); + } + } + } + if (event.type == sf::Event::MouseButtonPressed) { + this->editorContent.removeSelections(); + auto mousepos = sf::Mouse::getPosition(window); + auto mousepos_text = window.mapPixelToCoords(mousepos); + + // inicio seleccion cuando clickeo. + // Borro desde fuera explicitamente las selecciones + // Una seleccion inicial selecciona el propio caracter en el que estoy + // TODO: Multiples selecciones, sin borrar anteriores si presiono ctrl + std::pair docCoords = textView.getDocumentCoords(mousepos_text.x, mousepos_text.y); + this->editorContent.createNewSelection(docCoords.first, docCoords.second); + + this->mouseDown = true; + } + + if (event.type == sf::Event::MouseButtonReleased) { + this->mouseDown = false; + } +} + +void InputController::handleKeyPressedEvents(EditorView& textView, sf::Event& event) { + if (event.type == sf::Event::KeyPressed) { + bool isCtrlPressed = sf::Keyboard::isKeyPressed(sf::Keyboard::LControl) || sf::Keyboard::isKeyPressed(sf::Keyboard::RControl); + + bool isShiftPressed = sf::Keyboard::isKeyPressed(sf::Keyboard::LShift) || sf::Keyboard::isKeyPressed(sf::Keyboard::RShift); + + bool isEndPressed = sf::Keyboard::isKeyPressed(sf::Keyboard::End); + + bool isHomePressed = sf::Keyboard::isKeyPressed(sf::Keyboard::Home); + + if (event.key.code == sf::Keyboard::LShift || event.key.code == sf::Keyboard::RShift) { + if (!this->shiftPressed && !isCtrlPressed) { + this->shiftPressed = true; + // Si no hay una seleccion activa, empiezo una seleccion donde esten los cursores + this->editorContent.removeSelections(); + this->editorContent.createNewSelectionFromCursor(); + return; + } + } + + //Move to END + if (isEndPressed) { + editorContent.moveCursorToEnd(isShiftPressed); + return; + } + else if (isHomePressed) { //Move to LINE_START + editorContent.moveCursorToStart(isShiftPressed); + return; + } + + bool ctrlAndShift = isCtrlPressed && isShiftPressed; + + if (isCtrlPressed) { + if (event.key.code == sf::Keyboard::D) { + editorContent.duplicateCursorLine(); + } + else if (event.key.code == sf::Keyboard::U) { + editorContent.deleteSelections(); + sf::String emoji = "\\_('-')_/"; + editorContent.addTextInCursorPos(emoji); + } + else if (event.key.code == sf::Keyboard::C) { //Copy command, Ctrl + C + this->stringCopied = editorContent.copySelections(); + if (this->stringCopied.isEmpty()) { + this->stringCopied = editorContent.getCursorLine(); + } + } + else if (event.key.code == sf::Keyboard::V) { //Paste command, Ctrl + V + editorContent.addTextInCursorPos(stringCopied); + } + else if (event.key.code == sf::Keyboard::X) { //Cut command, Ctrl + X + this->stringCopied = editorContent.copySelections(); + editorContent.deleteSelections(); + } + } + + // TODO: Swapping selections is buggy + if (event.key.code == sf::Keyboard::Up) { + if (ctrlAndShift) { + editorContent.swapSelectedLines(true); + editorContent.moveCursorUp(true); + return; + } + else { + editorContent.moveCursorUp(this->shiftPressed); + return; + } + } + if (event.key.code == sf::Keyboard::Down) { + if (ctrlAndShift) { + editorContent.swapSelectedLines(false); + editorContent.moveCursorDown(true); + return; + } + else { + editorContent.moveCursorDown(this->shiftPressed); + return; + } + } + if (event.key.code == sf::Keyboard::Left) { + editorContent.moveCursorLeft(this->shiftPressed && !isCtrlPressed); + return; + } + if (event.key.code == sf::Keyboard::Right) { + editorContent.moveCursorRight(this->shiftPressed && !isCtrlPressed); + return; + } + + if (event.key.control) { + if (event.key.code == sf::Keyboard::Add) { + textView.zoomIn(); + return; + } + if (event.key.code == sf::Keyboard::Subtract) { + textView.zoomOut(); + return; + } + } + } +} + +void InputController::handleKeyReleasedEvents(sf::Event& event) { + if (event.type == sf::Event::KeyReleased) { + if (event.key.code == sf::Keyboard::LShift || event.key.code == sf::Keyboard::RShift) { + this->shiftPressed = sf::Keyboard::isKeyPressed(sf::Keyboard::LShift) || sf::Keyboard::isKeyPressed(sf::Keyboard::RShift); + } + } +} + +void InputController::handleTextEnteredEvent(EditorView& textView, sf::Event& event) { + if (event.type == sf::Event::TextEntered) { + bool ctrlPressed = sf::Keyboard::isKeyPressed(sf::Keyboard::LControl); + sf::String input(event.text.unicode); + + if (event.text.unicode == '\b') { + bool selecionDeleted = editorContent.deleteSelections(); + if (!selecionDeleted) { + editorContent.deleteTextBeforeCursorPos(1); + } + } + else if (event.text.unicode == 127) { // 127 = delete (supr) + bool selecionDeleted = editorContent.deleteSelections(); + if (!selecionDeleted) { + editorContent.deleteTextAfterCursorPos(1); + } + // Escribir normalmente solo si ctrl no esta presionado + } + else if (!ctrlPressed) { + if (event.text.unicode == '\t') { + // TODO: Cantidad de espacios de tab una variable + std::cerr << "TABS ACTIVADOS " << std::endl; + // input = " "; + } + + editorContent.deleteSelections(); + editorContent.addTextInCursorPos(input); + } + } +} + +bool InputController::isMouseDown() { + return this->mouseDown; +} + +// TODO: Agregar parametros para saber si tengo que agregar otro, actualizar selecciones o lo que sea +// TODO: Esta funcion solo sirve para la ultima seleccion, manejarlo por parametros?? +void InputController::updateCursorInEditor(EditorView& textView, float mouseX, float mouseY) { + std::pair docCoords = textView.getDocumentCoords(mouseX, mouseY); + int line = docCoords.first; + int column = docCoords.second; + + this->editorContent.resetCursor(line, column); + + // ESTO ASUME QUE PUEDO HACER UNA UNICA SELECCION + // TODO: Usar los metodos moveSelections para mover todas las selecciones. + this->editorContent.updateLastSelection(line, column); +} \ No newline at end of file diff --git a/Input.h b/Input.h new file mode 100644 index 0000000..7b9634f --- /dev/null +++ b/Input.h @@ -0,0 +1,33 @@ + +#ifndef InputController_H +#define InputController_H + +#include +#include + +#include "EditorView.h" +#include "Content.h" + +class InputController { +public: + InputController(EditorContent& editorContent); + void handleConstantInput(EditorView& view, sf::RenderWindow& window); + void handleEvents(EditorView& view, sf::RenderWindow& window, sf::Event& event); + bool isMouseDown(); + +private: + void handleMouseEvents(EditorView& view, sf::RenderWindow& window, sf::Event& event); + void handleKeyPressedEvents(EditorView& view, sf::Event& event); + void handleKeyReleasedEvents(sf::Event& event); + void handleTextEnteredEvent(EditorView& view, sf::Event& event); + + void updateCursorInEditor(EditorView& textView, float mouseX, float mouseY); + + bool mouseDown; + bool shiftPressed; + sf::String stringCopied; + + EditorContent& editorContent; +}; + +#endif \ No newline at end of file diff --git a/LICENSE b/LICENSE index 6bdfbc5..24cab55 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2018 Jonathan Seijo - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +MIT License + +Copyright (c) 2018 Jonathan Seijo + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Logo.h b/Logo.h new file mode 100644 index 0000000..4a64b97 --- /dev/null +++ b/Logo.h @@ -0,0 +1,126 @@ +#pragma once + +#include "Background.h" + +#include "SFML/Graphics.hpp" +#include +#include + +sf::Color whColor = sf::Color::White; +sf::Color lgColor = sf::Color{ 28, 30, 38 }; +sf::Color Transparency = sf::Color{ 255,255,255,128 }; + +sf::ConvexShape polygonLogo[6]; +using namespace sf; + +int PosX = 200, PosY = 50; + +sf::Event ev; + +void Drawlogo(sf::RenderWindow& window) { + + + for (int i = 0; i < 6; i++) { + polygon[i].setFillColor(sf::Color::White); + } + + polygonLogo[0].setPointCount(3); + polygonLogo[0].setFillColor(whColor); + polygonLogo[0].setPoint(0, Vector2f(300, 300)); + polygonLogo[0].setPoint(1, Vector2f(300, 0)); + polygonLogo[0].setPoint(2, Vector2f(0, 100)); + polygonLogo[0].setPosition(PosX, PosY); + + window.waitEvent(ev); + + polygonLogo[1].setPointCount(3); + polygonLogo[1].setFillColor(whColor); + polygonLogo[1].setPoint(0, Vector2f(300, 300)); + polygonLogo[1].setPoint(1, Vector2f(600, 100)); + polygonLogo[1].setPoint(2, Vector2f(300, 0)); + polygonLogo[1].setPosition(PosX, PosY); + + + polygonLogo[2].setPointCount(3); + polygonLogo[2].setFillColor(whColor); + polygonLogo[2].setPoint(0, Vector2f(300, 300)); + polygonLogo[2].setPoint(1, Vector2f(600, 100)); + polygonLogo[2].setPoint(2, Vector2f(600, 500)); + polygonLogo[2].setPosition(PosX + 10, PosY); + + + polygonLogo[3].setPointCount(3); + polygonLogo[3].setFillColor(whColor); + polygonLogo[3].setPoint(0, Vector2f(300, 300)); + polygonLogo[3].setPoint(1, Vector2f(600, 500)); + polygonLogo[3].setPoint(2, Vector2f(300, 600)); + polygonLogo[3].setPosition(PosX, PosY); + + + polygonLogo[4].setPointCount(3); + polygonLogo[4].setFillColor(whColor); + polygonLogo[4].setPoint(0, Vector2f(300, 300)); + polygonLogo[4].setPoint(1, Vector2f(0, 500)); + polygonLogo[4].setPoint(2, Vector2f(300, 600)); + polygonLogo[4].setPosition(PosX, PosY); + + + polygonLogo[5].setPointCount(3); + polygonLogo[5].setFillColor(whColor); + polygonLogo[5].setPoint(0, Vector2f(300, 300)); + polygonLogo[5].setPoint(1, Vector2f(0, 100)); + polygonLogo[5].setPoint(2, Vector2f(0, 500)); + polygonLogo[5].setPosition(PosX - 10, PosY); + + for (int i = 0; i < 6; i++) + { + + window.draw(polygonLogo[i]); + //polygonLogo[i].setPosition(30, 30); + } + window.display(); + + for (int i = 0; i < 6; i++) + { + window.draw(polygonLogo[i]); + } + + window.display(); + + if (window.waitEvent(ev)) { + for (int i = 0; i < 6; i++){ + polygonLogo[i].setFillColor(lgColor); + + for (int i = 0; i < 6; i++) { + window.draw(polygonLogo[i]); + } + + window.display(); + + // ========< TIME CHANGE CIRCLE COLOR >========= + std::this_thread::sleep_for(std::chrono::milliseconds(90)); + } + } + window.display(); + + int8_t TransparencyValue = 255; + + /* + [&]() { + while(TransparencyValue <= 0){ + + for (int i = 0; i < 6; i++) + { + polygonLogo[i].setFillColor(sf::Color(255,255,255, TransparencyValue)); + } + for (int i = 0; i < 6; i++) + { + window.draw(polygonLogo[i]); + } + TransparencyValue -= 2; + std::this_thread::sleep_for(std::chrono::milliseconds(30)); + } + window.display(); + }; + */ +} \ No newline at end of file diff --git a/Makefile b/Makefile index 8a2d692..df820a3 100644 --- a/Makefile +++ b/Makefile @@ -1,57 +1,57 @@ -# Adaptado de http://stackoverflow.com/a/30142139 - -GPP = g++ -SFML_VERSION=2.5.1 - -SFML_LIB=/usr/local/lib/SFML-$(SFML_VERSION)/lib -SFML_HEADERS=/usr/local/lib/SFML-$(SFML_VERSION)/include - -FLAGS = -std=c++11 -Wall -L $(SFML_LIB) -I $(SFML_HEADERS) -LIBS= -lsfml-graphics -lsfml-window -lsfml-system - -# Final binary -BIN = editor - -# Put all auto generated stuff to this build dir. -BUILD_DIR = ./build - -# List of all .cpp source files. -# CPP = main.cpp $(wildcard dir1/*.cpp) $(wildcard dir2/*.cpp) -CPP = Editor.cpp $(wildcard src/*.cpp) - -# All .o files go to build dir. -OBJ = $(CPP:%.cpp=$(BUILD_DIR)/%.o) - -# Gcc/Clang will create these .d files containing dependencies. -DEP = $(OBJ:%.o=%.d) - -# Default target named after the binary. -$(BIN) : $(BUILD_DIR)/$(BIN) - -# Actual target of the binary - depends on all .o files. -$(BUILD_DIR)/$(BIN) : $(OBJ) -# Create build directories - same structure as sources. - @mkdir -p $(@D) -# Just link all the object files. - $(GPP) $(FLAGS) $^ -o $@ $(LIBS) -# Solo por conveniencia, para poder hacer ./editor facilmente - @mv $(BUILD_DIR)/$(BIN) $(BIN) - -# Include all .d files --include $(DEP) - -# Build target for every single object file. -# The potential dependency on header files is covered -# by calling `-include $(DEP)`. -$(BUILD_DIR)/%.o : %.cpp - @mkdir -p $(@D) -# The -MMD flags additionaly creates a .d file with -# the same name as the .o file. - $(GPP) $(FLAGS) -MMD -c $< -I src/ -o $@ - -.PHONY : clean -clean : -# This should remove all generated files. - -rm -f $(BUILD_DIR)/$(BIN) $(OBJ) $(DEP) - rm -f editor #Why remove the executable too? - rmdir build/src build +# Adaptado de http://stackoverflow.com/a/30142139 + +GPP = g++ +SFML_VERSION=2.5.1 + +SFML_LIB=/usr/local/lib/SFML-$(SFML_VERSION)/lib +SFML_HEADERS=/usr/local/lib/SFML-$(SFML_VERSION)/include + +FLAGS = -std=c++11 -Wall -L $(SFML_LIB) -I $(SFML_HEADERS) +LIBS= -lsfml-graphics -lsfml-window -lsfml-system + +# Final binary +BIN = editor + +# Put all auto generated stuff to this build dir. +BUILD_DIR = ./build + +# List of all .cpp source files. +# CPP = main.cpp $(wildcard dir1/*.cpp) $(wildcard dir2/*.cpp) +CPP = Editor.cpp $(wildcard src/*.cpp) + +# All .o files go to build dir. +OBJ = $(CPP:%.cpp=$(BUILD_DIR)/%.o) + +# Gcc/Clang will create these .d files containing dependencies. +DEP = $(OBJ:%.o=%.d) + +# Default target named after the binary. +$(BIN) : $(BUILD_DIR)/$(BIN) + +# Actual target of the binary - depends on all .o files. +$(BUILD_DIR)/$(BIN) : $(OBJ) +# Create build directories - same structure as sources. + @mkdir -p $(@D) +# Just link all the object files. + $(GPP) $(FLAGS) $^ -o $@ $(LIBS) +# Solo por conveniencia, para poder hacer ./editor facilmente + @mv $(BUILD_DIR)/$(BIN) $(BIN) + +# Include all .d files +-include $(DEP) + +# Build target for every single object file. +# The potential dependency on header files is covered +# by calling `-include $(DEP)`. +$(BUILD_DIR)/%.o : %.cpp + @mkdir -p $(@D) +# The -MMD flags additionaly creates a .d file with +# the same name as the .o file. + $(GPP) $(FLAGS) -MMD -c $< -I src/ -o $@ + +.PHONY : clean +clean : +# This should remove all generated files. + -rm -f $(BUILD_DIR)/$(BIN) $(OBJ) $(DEP) + rm -f editor #Why remove the executable too? + rmdir build/src build diff --git a/MenuBar.cpp b/MenuBar.cpp new file mode 100644 index 0000000..994225c --- /dev/null +++ b/MenuBar.cpp @@ -0,0 +1,77 @@ +#include "MenuBar.h" +#include + +MenuBar::MenuBar( + const sf::RenderWindow &window, + EditorContent &EditorContent) : + content(EditorContent), Camera(sf::FloatRect(-40, 0, window.getSize().x, window.getSize().y)), + deltaScroll(20), deltaRotation(2), deltaZoomIn(0.8f), deltaZoomOut(1.2f), + rect(sf::Vector2f(500,30)) { + + // ===< FONT >=== + // this->font.loadFromFile("fonts/"); + + +} + +void MenuBar::drawLines(sf::RenderWindow& window) { + + for (int lineNumber = 0; lineNumber < 10; lineNumber++) { + sf::String line = this->content.getLine(lineNumber); + + sf::String currentLineText = ""; + + // TODO: Esto es al pe? + this->rightLimitPx = std::max((int)this->rightLimitPx, (int)(this->charWidth * line.getSize())); + + float offsetx = 0; + bool previousSelected = false; + + for (int charIndexInLine = 0; charIndexInLine <= (int)line.getSize(); charIndexInLine++) { + // En general hay una unica seleccion, en el futuro podria haber mas de una + bool currentSelected = content.isSelected(lineNumber, charIndexInLine); + + + + // Voy acumulando la string de la linea actual + currentLineText += line[charIndexInLine]; + } + } +} + +void MenuBar::draw(sf::RenderWindow& window) { + // this->drawLines(window); + + // Dibujo los numeros de la izquierda + + // TODO: Hacer una clase separada para el margin + for (int lineNumber = 1; lineNumber <= 6; lineNumber++) { + int lineHeight = 1; + + int blockHeight = lineHeight * this->fontSize; + + // sf::Text lineNumberText; + // lineNumberText.setFillColor(sf::Color::White); + // lineNumberText.setFont(this->font); + // lineNumberText.setString(std::to_string(lineNumber)); + // lineNumberText.setCharacterSize(this->fontSize - 1); + // lineNumberText.setPosition(-this->marginXOffset, blockHeight * (lineNumber - 1)); + + // sf::RectangleShape marginRect(sf::Vector2f(this->marginXOffset - 5, blockHeight)); + // marginRect.setFillColor(this->colorMargin); + // marginRect.setFillColor(sf::Color{200,200,200}); + // marginRect.setPosition(-this->marginXOffset, blockHeight * (lineNumber - 1)); + // + // window.draw(marginRect); + // window.draw(lineNumberText); + + sf::RectangleShape RectBar; + RectBar.setSize(sf::Vector2f(1200, 520)); + RectBar.setOutlineColor(sf::Color::Red); + RectBar.setOutlineThickness(5); + RectBar.setPosition(110, 210); + window.draw(RectBar); + + } + +} \ No newline at end of file diff --git a/MenuBar.h b/MenuBar.h new file mode 100644 index 0000000..ceb94ac --- /dev/null +++ b/MenuBar.h @@ -0,0 +1,47 @@ +#pragma once + + +#include "Content.h" +#include "SFML/Graphics.hpp" + +class MenuBar { + +public: + + MenuBar(const sf::RenderWindow &window, EditorContent &content); + void draw(sf::RenderWindow &window); + void drawLines(sf::RenderWindow &window); + +private: + + EditorContent& content; + + // ===< BACKGROUND >=== + sf::RectangleShape rect; + + + sf::Font font; + + float rightLimitPx; + float bottomLimitPx; + + + int fontSize = 13; + int marginXOffset; + sf::Color colorMargin; + + int MaxFontSize = 40; + int MinFontSize = 9; + + int lineHeight; + int charWidth; + + sf::Color colorChar; + sf::Color colorSelection; + + + sf::View Camera; + float deltaScroll; + float deltaRotation; + float deltaZoomIn, deltaZoomOut; +}; \ No newline at end of file diff --git a/README.md b/README.md index c5e60ac..f81c53f 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,45 @@ -# text-editor -Text editor made in C++ using SFML - -This is a simple text editor made from scratch in C++. (Using SFML for window drawing) -Yes, thats it. Nothing fancy, nothing weird. Just a great learning experience. - -![Simple example](https://raw.githubusercontent.com/JonSeijo/text-editor/master/img/super_example.gif) - -The editor is functional, you can write text, delete it, select it (keyboard AND mouse support). It has some nice features like swapping text lines. - -![Swapping lines](https://raw.githubusercontent.com/JonSeijo/text-editor/master/img/moving_lines.gif) - ----- - -## Compiling instructions - -The editor uses SFML library as graphics controller, so it is needed for compiling. IMPORTANT: Needs version +2.4 !! -See https://www.sfml-dev.org - -A working Makefile is included, works great assuming you have sfml installed correctly. - -``` -make && ./editor -``` - -## Warning! - -Be careful with the data you save! - - -## F.A.Q. - -![Swapping lines](https://raw.githubusercontent.com/JonSeijo/text-editor/master/img/but_why.gif) - - -## Notes - -DejaVuSansMono.ttf -https://dejavu-fonts.github.io/ - -FreeMono.ttf -http://font.ubuntu.com/ufl/ubuntu-font-licence-1.0.txt - -SFML 2.4 -https://www.sfml-dev.org +# text-editor +Text editor made in C++ using SFML + +This is a simple text editor made from scratch in C++. (Using SFML for window drawing) +Yes, thats it. Nothing fancy, nothing weird. Just a great learning experience. + +![Simple example](https://raw.githubusercontent.com/JonSeijo/text-editor/master/img/super_example.gif) + +The editor is functional, you can write text, delete it, select it (keyboard AND mouse support). It has some nice features like swapping text lines. + +![Swapping lines](https://raw.githubusercontent.com/JonSeijo/text-editor/master/img/moving_lines.gif) + +---- + +## Compiling instructions + +The editor uses SFML library as graphics controller, so it is needed for compiling. IMPORTANT: Needs version +2.4 !! +See https://www.sfml-dev.org + +A working Makefile is included, works great assuming you have sfml installed correctly. + +``` +make && ./editor +``` + +## Warning! + +Be careful with the data you save! + + +## F.A.Q. + +![Swapping lines](https://raw.githubusercontent.com/JonSeijo/text-editor/master/img/but_why.gif) + + +## Notes + +DejaVuSansMono.ttf +https://dejavu-fonts.github.io/ + +FreeMono.ttf +http://font.ubuntu.com/ufl/ubuntu-font-licence-1.0.txt + +SFML 2.4 +https://www.sfml-dev.org diff --git a/SData.cpp b/SData.cpp new file mode 100644 index 0000000..0143046 --- /dev/null +++ b/SData.cpp @@ -0,0 +1,135 @@ +#include "Document.h" + +SelectionData::SelectionData() : lastSelectionIndex(-1) {} + +// Inactiva por defecto pues solo inicializo el ancla +void SelectionData::createNewSelection(int anclaLine, int anclaChar) { + this->selections.push_back(Selection(anclaLine, anclaChar)); + this->lastSelectionIndex++; +} + +void SelectionData::updateLastSelection(int extremoLine, int extremoChar) { + if (this->lastSelectionIndex < 0) { + return; + } + + int anclaLine = this->getLastAnclaLine(); + int anclaChar = this->getLastAnclaChar(); + + bool nuevaActiva = (anclaLine != extremoLine) || (anclaChar != extremoChar); + this->selections[this->lastSelectionIndex].activa = nuevaActiva; + + this->selections[this->lastSelectionIndex].extremo.lineN = extremoLine; + this->selections[this->lastSelectionIndex].extremo.charN = extremoChar; +} + +// Extremos de una seleccion son inclusives a ambos lados +bool SelectionData::isSelected(int lineN, int charN) const { + for (const Selection sel : this->selections) { + if (!sel.activa) { + continue; + } + // std::cout << "A" << std::endl; + SelectionData::Extremo start; + SelectionData::Extremo end; + + if (sel.ancla < sel.extremo) { + start = sel.ancla; + end = sel.extremo; + } + else { + start = sel.extremo; + end = sel.ancla; + } + + // Si esta estrictamente entre las lineas puede estar seleccionado. + if (start.lineN <= lineN && lineN <= end.lineN) { + // Si la linea esta estrictamente contenida es porque esta seleccionada + if (start.lineN < lineN && lineN < end.lineN) { + return true; + } + + // Si hay mas de una linea de seleccion y esta en el inicio + else if (start.lineN == lineN && lineN < end.lineN) { + if (start.charN <= charN) { + return true; + } + } + + // Si hay mas de una linea de seleccion y esta en el final + else if (start.lineN < lineN && lineN == end.lineN) { + if (charN < end.charN) { + return true; + } + } + + // Si hay una unica linea de seleccion y está ahi + else if (start.lineN == lineN && lineN == end.lineN) { + if (start.charN <= charN && charN < end.charN) { + return true; + } + } + } + } + return false; +} + +void SelectionData::removeSelections() { + int lastIndex = this->selections.size() - 1; + for (int i = lastIndex; i >= 0; i--) { + this->removeSelection(i); + } +} + +void SelectionData::removeSelection(int index) { + this->validIndex(index); + this->selections.erase(this->selections.begin() + index); + this->lastSelectionIndex--; +} + +SelectionData::Selection SelectionData::getLastSelection() { + if (this->validIndex(this->lastSelectionIndex)) { + return this->selections[this->lastSelectionIndex]; + } + return SelectionData::Selection(); +} + +int SelectionData::getStartLineN(Selection& selection) { + auto extremoStart = selection.ancla < selection.extremo ? selection.ancla : selection.extremo; + return extremoStart.lineN; +} + +int SelectionData::getStartCharN(Selection& selection) { + auto extremoStart = selection.ancla < selection.extremo ? selection.ancla : selection.extremo; + return extremoStart.charN; +} + +int SelectionData::getEndLineN(Selection& selection) { + auto extremoEnd = selection.ancla < selection.extremo ? selection.extremo : selection.ancla; + return extremoEnd.lineN; +} + +int SelectionData::getEndCharN(Selection& selection) { + auto extremoEnd = selection.ancla < selection.extremo ? selection.extremo : selection.ancla; + return extremoEnd.charN; +} + +bool SelectionData::validIndex(int index) { + if (index < 0 || index >= (int)this->selections.size()) { + // std::cerr << "Index: " << index << " is not a valid index for Selections" << std::endl; + return false; + } + return true; +} + +int SelectionData::getLastAnclaLine() { + return this->selections[this->lastSelectionIndex].ancla.lineN; +} + +int SelectionData::getLastAnclaChar() { + return this->selections[this->lastSelectionIndex].ancla.charN; +} + +int SelectionData::getLastIsActive() { + return this->selections[this->lastSelectionIndex].activa; +} \ No newline at end of file diff --git a/SData.h b/SData.h new file mode 100644 index 0000000..a4716dd --- /dev/null +++ b/SData.h @@ -0,0 +1,76 @@ +#pragma once + +// THERE ARE IN DOCUMENT.H + +#ifndef SelectionData_H +#define SelectionData_H + +#include +#include + +#include "Document.h" + +// TODO: Pensar si la seleccion no deberia conocer al documento, para arreglar quilombos con los multiples +// TODO: Avanzar/retroceder un char. Avanzar/retroceder una palabra +class SelectionData { +private: + struct Extremo { + Extremo() : lineN(-1), charN(-1) {} + Extremo(int lineN, int charN) : lineN(lineN), charN(charN) {}; + int lineN; + int charN; + + bool operator<(const Extremo& ex) const { + return lineN < ex.lineN || (lineN <= ex.lineN && charN < ex.charN); + } + }; + +public: + SelectionData(); + + struct Selection { + Selection() : activa(false), ancla(), extremo() {} + Selection(int anclaLine, int anclaChar) : activa(false), ancla(anclaLine, anclaChar), extremo() {} + + bool activa; + SelectionData::Extremo ancla; + SelectionData::Extremo extremo; + }; + + void createNewSelection(int anclaLine, int anclaChar); + void updateLastSelection(int extremoLine, int extremoChar); + + + void removeSelections(); + bool isSelected(int lineN, int charN) const; + + Selection getLastSelection(); + + // TODO: Para cuando use multiples selecciones con teclado + // util para mover todas x caractes hacia un lado. + // Hay que tener en cuenta el no salirse del documento y cambios de linea, colisiones etc + // TODO: Puede que cada seleccion se necesite mover de a saltos diferentes, + // por ejemplo cuando muevo con ctrl shift de a palabras, esto no serviria en ese caso + // tendria que hacer un "moveSelectionsToNextWord" o algo asi + // TODO: Handlear que pasa cuando las selecciones chocan, ver el merge + void moveSelectionsRight(int charAmount, const TextDocument& doc); + void moveSelectionsLeft(int charAmount, const TextDocument& doc); + + static int getStartLineN(Selection& selection); + static int getStartCharN(Selection& selection); + static int getEndLineN(Selection& selection); + static int getEndCharN(Selection& selection); + +private: + std::vector selections; + int lastSelectionIndex; + + int getLastAnclaLine(); + int getLastAnclaChar(); + int getLastIsActive(); + + bool validIndex(int index); + void removeSelection(int index); +}; + +#endif \ No newline at end of file diff --git a/Source.cpp b/Source.cpp new file mode 100644 index 0000000..6bbc017 --- /dev/null +++ b/Source.cpp @@ -0,0 +1,109 @@ +#include + + +#include "SFML/Window.hpp" +#include "MenuBar.h" +#include "Logo.h" +#include "Icon.h" +#include "EditorView.h" +#include "Filesystem.h" +#include "Utills.h" +#include "Document.h" +#include "Content.h" +#include "Input.h" + +int main(int argc, char *argv[]) { + + sf::RectangleShape rectangle(sf::Vector2f(150, 80)); + sf::RenderWindow window(sf::VideoMode(1000, 700), "Nanoe"); + window.setVerticalSyncEnabled(true); + SetIcon(window); + + + // ======< WORKING DIRECTION >========================= + std::string Direction = Implementation::WorkingDirection(argv[0]); + + std::string LoadFile, SaveFile; + + if (argc == 2) { + LoadFile = Direction + argv[1]; + SaveFile = Direction + argv[1]; + } + else { + LoadFile = Direction + "text.txt"; + SaveFile = Direction + "text.txt"; + } + + // ===< DOCUMENT INIT >========== + TextDocument Document; + Document.init(LoadFile); + + EditorContent Content(Document); + + EditorView View(window, Direction, Content); + InputController Input(Content); + + // =======< MENU BAR >======== + MenuBar Menu(window, Content); + // Menu.draw(window); + + + + // =====< DRAWING LOGO BEFORE STARING >========= + Drawlogo(window); + + + + + while (window.isOpen()) { + sf::Event ev; + while (window.pollEvent(ev)) { + + // ======< WINDOW CLOSE >======= + if (ev.type == sf::Event::Closed) + window.close(); + + // =====< CAMERA POSITION >===== + if (ev.type == sf::Event::Resized) + View.setCameraBounds(ev.size.width, ev.size.height); + + // ========< FILE SAVE >======== + if (ev.key.code == sf::Keyboard::S && sf::Keyboard::isKeyPressed(sf::Keyboard::LControl)) { + if (Document.hasChanged()) { + Document.saveFile(SaveFile); + std::cout << "SAVED TO: " << SaveFile << "\n"; + } + } + + // =========< FONT SIZE CHANGE (ZOOM) >========== + if (sf::Keyboard::isKeyPressed(sf::Keyboard::LControl) && ev.type == sf::Event::MouseWheelScrolled) { + if (ev.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel) { + if (ev.mouseWheelScroll.delta <= -1) + View.FontSizeScrollChangeDown(); + else + View.FontSizeScrollChangeUp(); + } + break; + } + + // =========< IMPL CTRL + A >========= + if (sf::Keyboard::isKeyPressed(sf::Keyboard::LControl) && ev.key.code == sf::Keyboard::A) { + std::cout << "ctrl + a" << std::endl; + View.SelectAll(); + } + + Input.handleEvents(View, window, ev); + } + Input.handleConstantInput(View, window); + + window.clear(bgColor); + window.setView(View.getCameraView()); + View.draw(window); + window.display(); + // Backgroundcolor(window); + } + + + + return 0; +} \ No newline at end of file diff --git a/StatusBar.h b/StatusBar.h new file mode 100644 index 0000000..365b188 --- /dev/null +++ b/StatusBar.h @@ -0,0 +1,8 @@ +#pragma once + +// TODO +class StatusBasr { + + + +}; \ No newline at end of file diff --git a/Utills.h b/Utills.h new file mode 100644 index 0000000..db8398a --- /dev/null +++ b/Utills.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +class Implementation { + + public: + static std::string WorkingDirection(const std::string&); + + +}; \ No newline at end of file diff --git a/UtillsImplementation.cpp b/UtillsImplementation.cpp new file mode 100644 index 0000000..4ee2555 --- /dev/null +++ b/UtillsImplementation.cpp @@ -0,0 +1,8 @@ +#include "Utills.h" + +std::string Implementation::WorkingDirection(const std::string& str) { + + int i = str.find_last_of('/'); + + return str.substr(0, i + 1); +} \ No newline at end of file diff --git a/fonts/DejaVuMathTeXGyre.ttf b/fonts/DejaVuMathTeXGyre.ttf new file mode 100644 index 0000000..8a24f06 Binary files /dev/null and b/fonts/DejaVuMathTeXGyre.ttf differ diff --git a/fonts/DejaVuSans-Bold.ttf b/fonts/DejaVuSans-Bold.ttf new file mode 100644 index 0000000..6d65fa7 Binary files /dev/null and b/fonts/DejaVuSans-Bold.ttf differ diff --git a/fonts/DejaVuSans-BoldOblique.ttf b/fonts/DejaVuSans-BoldOblique.ttf new file mode 100644 index 0000000..753f2d8 Binary files /dev/null and b/fonts/DejaVuSans-BoldOblique.ttf differ diff --git a/fonts/DejaVuSans-ExtraLight.ttf b/fonts/DejaVuSans-ExtraLight.ttf new file mode 100644 index 0000000..b09f32d Binary files /dev/null and b/fonts/DejaVuSans-ExtraLight.ttf differ diff --git a/fonts/DejaVuSans-Oblique.ttf b/fonts/DejaVuSans-Oblique.ttf new file mode 100644 index 0000000..999bac7 Binary files /dev/null and b/fonts/DejaVuSans-Oblique.ttf differ diff --git a/fonts/DejaVuSans.ttf b/fonts/DejaVuSans.ttf new file mode 100644 index 0000000..e5f7eec Binary files /dev/null and b/fonts/DejaVuSans.ttf differ diff --git a/fonts/DejaVuSansCondensed-Bold.ttf b/fonts/DejaVuSansCondensed-Bold.ttf new file mode 100644 index 0000000..22987c6 Binary files /dev/null and b/fonts/DejaVuSansCondensed-Bold.ttf differ diff --git a/fonts/DejaVuSansCondensed-BoldOblique.ttf b/fonts/DejaVuSansCondensed-BoldOblique.ttf new file mode 100644 index 0000000..f5fa0ca Binary files /dev/null and b/fonts/DejaVuSansCondensed-BoldOblique.ttf differ diff --git a/fonts/DejaVuSansCondensed-Oblique.ttf b/fonts/DejaVuSansCondensed-Oblique.ttf new file mode 100644 index 0000000..7fde907 Binary files /dev/null and b/fonts/DejaVuSansCondensed-Oblique.ttf differ diff --git a/fonts/DejaVuSansCondensed.ttf b/fonts/DejaVuSansCondensed.ttf new file mode 100644 index 0000000..3259bc2 Binary files /dev/null and b/fonts/DejaVuSansCondensed.ttf differ diff --git a/fonts/DejaVuSansMono-Bold.ttf b/fonts/DejaVuSansMono-Bold.ttf new file mode 100644 index 0000000..8184ced Binary files /dev/null and b/fonts/DejaVuSansMono-Bold.ttf differ diff --git a/fonts/DejaVuSansMono-BoldOblique.ttf b/fonts/DejaVuSansMono-BoldOblique.ttf new file mode 100644 index 0000000..754dca7 Binary files /dev/null and b/fonts/DejaVuSansMono-BoldOblique.ttf differ diff --git a/fonts/DejaVuSansMono-Oblique.ttf b/fonts/DejaVuSansMono-Oblique.ttf new file mode 100644 index 0000000..4c858d4 Binary files /dev/null and b/fonts/DejaVuSansMono-Oblique.ttf differ diff --git a/fonts/DejaVuSerif-Bold.ttf b/fonts/DejaVuSerif-Bold.ttf new file mode 100644 index 0000000..3bb755f Binary files /dev/null and b/fonts/DejaVuSerif-Bold.ttf differ diff --git a/fonts/DejaVuSerif-BoldItalic.ttf b/fonts/DejaVuSerif-BoldItalic.ttf new file mode 100644 index 0000000..a36dd4b Binary files /dev/null and b/fonts/DejaVuSerif-BoldItalic.ttf differ diff --git a/fonts/DejaVuSerif-Italic.ttf b/fonts/DejaVuSerif-Italic.ttf new file mode 100644 index 0000000..805daf2 Binary files /dev/null and b/fonts/DejaVuSerif-Italic.ttf differ diff --git a/fonts/DejaVuSerif.ttf b/fonts/DejaVuSerif.ttf new file mode 100644 index 0000000..0b803d2 Binary files /dev/null and b/fonts/DejaVuSerif.ttf differ diff --git a/fonts/DejaVuSerifCondensed-Bold.ttf b/fonts/DejaVuSerifCondensed-Bold.ttf new file mode 100644 index 0000000..222bf13 Binary files /dev/null and b/fonts/DejaVuSerifCondensed-Bold.ttf differ diff --git a/fonts/DejaVuSerifCondensed-BoldItalic.ttf b/fonts/DejaVuSerifCondensed-BoldItalic.ttf new file mode 100644 index 0000000..e446636 Binary files /dev/null and b/fonts/DejaVuSerifCondensed-BoldItalic.ttf differ diff --git a/fonts/DejaVuSerifCondensed-Italic.ttf b/fonts/DejaVuSerifCondensed-Italic.ttf new file mode 100644 index 0000000..c529df3 Binary files /dev/null and b/fonts/DejaVuSerifCondensed-Italic.ttf differ diff --git a/fonts/DejaVuSerifCondensed.ttf b/fonts/DejaVuSerifCondensed.ttf new file mode 100644 index 0000000..d3959b3 Binary files /dev/null and b/fonts/DejaVuSerifCondensed.ttf differ diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..4c11d1b Binary files /dev/null and b/icon.png differ diff --git a/img/g.gif b/img/g.gif new file mode 100644 index 0000000..0573d84 Binary files /dev/null and b/img/g.gif differ diff --git a/run.sh b/run.sh index 8b82851..abb7469 100755 --- a/run.sh +++ b/run.sh @@ -1,2 +1,2 @@ -# Needed if SFML was downloaded manually +# Needed if SFML was downloaded manually LD_LIBRARY_PATH=/usr/local/lib/SFML-2.5.1/lib ./editor \ No newline at end of file diff --git a/text.txt b/text.txt new file mode 100644 index 0000000..da35e96 --- /dev/null +++ b/text.txt @@ -0,0 +1,2 @@ +Hello World +dasdH sa dasd ddddddddddddddf sdfs df sdsf sss sdfsd s sdsdasa assdasda \ No newline at end of file diff --git a/x64/Debug/Content.obj b/x64/Debug/Content.obj new file mode 100644 index 0000000..f588d8c Binary files /dev/null and b/x64/Debug/Content.obj differ diff --git a/x64/Debug/Cursor.obj b/x64/Debug/Cursor.obj new file mode 100644 index 0000000..97c5e38 Binary files /dev/null and b/x64/Debug/Cursor.obj differ diff --git a/x64/Debug/Document.obj b/x64/Debug/Document.obj new file mode 100644 index 0000000..3228275 Binary files /dev/null and b/x64/Debug/Document.obj differ diff --git a/x64/Debug/Editor.exe.recipe b/x64/Debug/Editor.exe.recipe new file mode 100644 index 0000000..96b5e84 --- /dev/null +++ b/x64/Debug/Editor.exe.recipe @@ -0,0 +1,11 @@ + + + + + D:\VS repos\Editor\x64\Debug\Editor.exe + + + + + + \ No newline at end of file diff --git a/x64/Debug/Editor.ilk b/x64/Debug/Editor.ilk new file mode 100644 index 0000000..81b2a8d Binary files /dev/null and b/x64/Debug/Editor.ilk differ diff --git a/x64/Debug/Editor.log b/x64/Debug/Editor.log new file mode 100644 index 0000000..55c0103 --- /dev/null +++ b/x64/Debug/Editor.log @@ -0,0 +1,93 @@ + EditorView.cpp +D:\VS repos\Editor\Editor\EditorView.cpp(12,70): warning C4244: 'argument': conversion from 'T' to 'T', possible loss of data + with + [ + T=unsigned int + ] + and + [ + T=float + ] +D:\VS repos\Editor\Editor\EditorView.cpp(12,50): warning C4244: 'argument': conversion from 'T' to 'T', possible loss of data + with + [ + T=unsigned int + ] + and + [ + T=float + ] +D:\VS repos\Editor\Editor\EditorView.cpp(60,23): warning C4244: '=': conversion from 'float' to 'int', possible loss of data +D:\VS repos\Editor\Editor\EditorView.cpp(97,70): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\EditorView.cpp(97,36): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\EditorView.cpp(99,77): warning C4244: 'argument': conversion from 'int' to 'T', possible loss of data + with + [ + T=float + ] +D:\VS repos\Editor\Editor\EditorView.cpp(99,72): warning C4244: 'argument': conversion from 'int' to 'T', possible loss of data + with + [ + T=float + ] +D:\VS repos\Editor\Editor\EditorView.cpp(101,66): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\EditorView.cpp(101,32): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\EditorView.cpp(128,54): warning C4244: '=': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\EditorView.cpp(135,38): warning C4244: '=': conversion from 'const _Ty' to 'float', possible loss of data + with + [ + _Ty=int + ] +D:\VS repos\Editor\Editor\EditorView.cpp(152,55): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\EditorView.cpp(157,79): warning C4244: 'argument': conversion from 'int' to 'T', possible loss of data + with + [ + T=float + ] +D:\VS repos\Editor\Editor\EditorView.cpp(157,54): warning C4244: 'argument': conversion from 'int' to 'T', possible loss of data + with + [ + T=float + ] +D:\VS repos\Editor\Editor\EditorView.cpp(160,58): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\EditorView.cpp(190,65): warning C4244: 'argument': conversion from 'int' to 'T', possible loss of data + with + [ + T=float + ] +D:\VS repos\Editor\Editor\EditorView.cpp(190,48): warning C4244: 'argument': conversion from 'int' to 'T', possible loss of data + with + [ + T=float + ] +D:\VS repos\Editor\Editor\EditorView.cpp(195,30): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\EditorView.cpp(194,16): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\EditorView.cpp(205,15): warning C4244: 'initializing': conversion from 'float' to 'int', possible loss of data +D:\VS repos\Editor\Editor\EditorView.cpp(224,20): warning C4244: 'initializing': conversion from 'float' to 'int', possible loss of data +D:\VS repos\Editor\Editor\EditorView.cpp(290,58): warning C4244: 'argument': conversion from 'int' to 'T', possible loss of data + with + [ + T=float + ] +D:\VS repos\Editor\Editor\EditorView.cpp(290,51): warning C4244: 'argument': conversion from 'int' to 'T', possible loss of data + with + [ + T=float + ] + Input.cpp + Source.cpp +D:\VS repos\Editor\Editor\Logo.h(32,35): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\Logo.h(32,29): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\Logo.h(41,35): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\Logo.h(41,29): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\Logo.h(49,40): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\Logo.h(49,34): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\Logo.h(57,35): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\Logo.h(57,29): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\Logo.h(65,35): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\Logo.h(65,29): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\Logo.h(73,40): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\Logo.h(73,34): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data +D:\VS repos\Editor\Editor\Logo.h(106,29): warning C4309: 'initializing': truncation of constant value + Generating Code... + Editor.vcxproj -> D:\VS repos\Editor\x64\Debug\Editor.exe diff --git a/x64/Debug/Editor.tlog/CL.command.1.tlog b/x64/Debug/Editor.tlog/CL.command.1.tlog new file mode 100644 index 0000000..07ea92d Binary files /dev/null and b/x64/Debug/Editor.tlog/CL.command.1.tlog differ diff --git a/x64/Debug/Editor.tlog/CL.read.1.tlog b/x64/Debug/Editor.tlog/CL.read.1.tlog new file mode 100644 index 0000000..7179265 Binary files /dev/null and b/x64/Debug/Editor.tlog/CL.read.1.tlog differ diff --git a/x64/Debug/Editor.tlog/CL.write.1.tlog b/x64/Debug/Editor.tlog/CL.write.1.tlog new file mode 100644 index 0000000..cba85e6 Binary files /dev/null and b/x64/Debug/Editor.tlog/CL.write.1.tlog differ diff --git a/x64/Debug/Editor.tlog/Editor.lastbuildstate b/x64/Debug/Editor.tlog/Editor.lastbuildstate new file mode 100644 index 0000000..9e848b7 --- /dev/null +++ b/x64/Debug/Editor.tlog/Editor.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.32.31326:TargetPlatformVersion=10.0.22621.0:VcpkgTriplet=x64-windows: +Debug|x64|D:\VS repos\Editor\| diff --git a/x64/Debug/Editor.tlog/link.command.1.tlog b/x64/Debug/Editor.tlog/link.command.1.tlog new file mode 100644 index 0000000..39a4521 Binary files /dev/null and b/x64/Debug/Editor.tlog/link.command.1.tlog differ diff --git a/x64/Debug/Editor.tlog/link.read.1.tlog b/x64/Debug/Editor.tlog/link.read.1.tlog new file mode 100644 index 0000000..aa39512 Binary files /dev/null and b/x64/Debug/Editor.tlog/link.read.1.tlog differ diff --git a/x64/Debug/Editor.tlog/link.write.1.tlog b/x64/Debug/Editor.tlog/link.write.1.tlog new file mode 100644 index 0000000..aa1182a Binary files /dev/null and b/x64/Debug/Editor.tlog/link.write.1.tlog differ diff --git a/x64/Debug/EditorView.obj b/x64/Debug/EditorView.obj new file mode 100644 index 0000000..cd9c431 Binary files /dev/null and b/x64/Debug/EditorView.obj differ diff --git a/x64/Debug/Enumaration.obj b/x64/Debug/Enumaration.obj new file mode 100644 index 0000000..ed466e8 Binary files /dev/null and b/x64/Debug/Enumaration.obj differ diff --git a/x64/Debug/Input.obj b/x64/Debug/Input.obj new file mode 100644 index 0000000..54cb8ff Binary files /dev/null and b/x64/Debug/Input.obj differ diff --git a/x64/Debug/MenuBar.obj b/x64/Debug/MenuBar.obj new file mode 100644 index 0000000..9bc3836 Binary files /dev/null and b/x64/Debug/MenuBar.obj differ diff --git a/x64/Debug/SData.obj b/x64/Debug/SData.obj new file mode 100644 index 0000000..2142c41 Binary files /dev/null and b/x64/Debug/SData.obj differ diff --git a/x64/Debug/Source.obj b/x64/Debug/Source.obj new file mode 100644 index 0000000..6f9f406 Binary files /dev/null and b/x64/Debug/Source.obj differ diff --git a/x64/Debug/UtillsImplementation.obj b/x64/Debug/UtillsImplementation.obj new file mode 100644 index 0000000..aa51990 Binary files /dev/null and b/x64/Debug/UtillsImplementation.obj differ diff --git a/x64/Debug/vc143.idb b/x64/Debug/vc143.idb new file mode 100644 index 0000000..2b4f6b6 Binary files /dev/null and b/x64/Debug/vc143.idb differ diff --git a/x64/Debug/vc143.pdb b/x64/Debug/vc143.pdb new file mode 100644 index 0000000..d75a11b Binary files /dev/null and b/x64/Debug/vc143.pdb differ diff --git a/x64/Debug/vcpkg.applocal.log b/x64/Debug/vcpkg.applocal.log new file mode 100644 index 0000000..e02abfc --- /dev/null +++ b/x64/Debug/vcpkg.applocal.log @@ -0,0 +1 @@ + diff --git a/x64/Release/Editor.exe.recipe b/x64/Release/Editor.exe.recipe new file mode 100644 index 0000000..baedf3b --- /dev/null +++ b/x64/Release/Editor.exe.recipe @@ -0,0 +1,11 @@ + + + + + D:\VS repos\Editor\x64\Release\Editor.exe + + + + + + \ No newline at end of file diff --git a/x64/Release/Editor.iobj b/x64/Release/Editor.iobj new file mode 100644 index 0000000..e441ddb Binary files /dev/null and b/x64/Release/Editor.iobj differ diff --git a/x64/Release/Editor.ipdb b/x64/Release/Editor.ipdb new file mode 100644 index 0000000..778d801 Binary files /dev/null and b/x64/Release/Editor.ipdb differ diff --git a/x64/Release/Editor.log b/x64/Release/Editor.log new file mode 100644 index 0000000..bcbb337 --- /dev/null +++ b/x64/Release/Editor.log @@ -0,0 +1,6 @@ + Source.cpp + Generating code + Previous IPDB not found, fall back to full compilation. + All 1 functions were compiled because no usable IPDB/IOBJ from previous compilation was found. + Finished generating code + Editor.vcxproj -> D:\VS repos\Editor\x64\Release\Editor.exe diff --git a/x64/Release/Editor.tlog/CL.command.1.tlog b/x64/Release/Editor.tlog/CL.command.1.tlog new file mode 100644 index 0000000..8851076 Binary files /dev/null and b/x64/Release/Editor.tlog/CL.command.1.tlog differ diff --git a/x64/Release/Editor.tlog/CL.read.1.tlog b/x64/Release/Editor.tlog/CL.read.1.tlog new file mode 100644 index 0000000..03ed49f Binary files /dev/null and b/x64/Release/Editor.tlog/CL.read.1.tlog differ diff --git a/x64/Release/Editor.tlog/CL.write.1.tlog b/x64/Release/Editor.tlog/CL.write.1.tlog new file mode 100644 index 0000000..d88bcac Binary files /dev/null and b/x64/Release/Editor.tlog/CL.write.1.tlog differ diff --git a/x64/Release/Editor.tlog/Editor.lastbuildstate b/x64/Release/Editor.tlog/Editor.lastbuildstate new file mode 100644 index 0000000..be983bf --- /dev/null +++ b/x64/Release/Editor.tlog/Editor.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.32.31326:TargetPlatformVersion=10.0.22621.0:VcpkgTriplet=x64-windows: +Release|x64|D:\VS repos\Editor\| diff --git a/x64/Release/Editor.tlog/link.command.1.tlog b/x64/Release/Editor.tlog/link.command.1.tlog new file mode 100644 index 0000000..0f66242 Binary files /dev/null and b/x64/Release/Editor.tlog/link.command.1.tlog differ diff --git a/x64/Release/Editor.tlog/link.read.1.tlog b/x64/Release/Editor.tlog/link.read.1.tlog new file mode 100644 index 0000000..2ad20a3 Binary files /dev/null and b/x64/Release/Editor.tlog/link.read.1.tlog differ diff --git a/x64/Release/Editor.tlog/link.write.1.tlog b/x64/Release/Editor.tlog/link.write.1.tlog new file mode 100644 index 0000000..aee786c Binary files /dev/null and b/x64/Release/Editor.tlog/link.write.1.tlog differ diff --git a/x64/Release/Source.obj b/x64/Release/Source.obj new file mode 100644 index 0000000..cdab9f8 Binary files /dev/null and b/x64/Release/Source.obj differ diff --git a/x64/Release/vc143.pdb b/x64/Release/vc143.pdb new file mode 100644 index 0000000..9f88efc Binary files /dev/null and b/x64/Release/vc143.pdb differ diff --git a/x64/Release/vcpkg.applocal.log b/x64/Release/vcpkg.applocal.log new file mode 100644 index 0000000..e02abfc --- /dev/null +++ b/x64/Release/vcpkg.applocal.log @@ -0,0 +1 @@ +