Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
//
// ECEditor.cpp
//
// created by Daniel Backal
// 03/04/2020
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include "ECEditor.h"
#include <iostream>
#include <string>
using namespace std;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Controller for the ECEditor
class InsertCommand : public ECCommand
{
public:
InsertCommand(int xcursor, int ycursor, int key, ECDocument &docIn) : x(xcursor), y(ycursor), k(key), doc(docIn)
{
}
void Execute()
{
doc.InsertCharAt(x, y, k);
return;
}
void UnExecute()
{
doc.RemoveCharAt(x+1, y);
return;
}
private:
int x;
int y;
int k;
ECDocument &doc;
};
class RemoveCommand : public ECCommand
{
public:
RemoveCommand(int xcursor, int ycursor, ECDocument &docIn) : x(xcursor), y(ycursor), doc(docIn)
{
k = doc.GetCharAt(x, y);
if (k == ENTER)
{
enterx = doc.GetRowSizeAt(y-1);
}
}
void Execute()
{
doc.RemoveCharAt(x, y);
return;
}
void UnExecute()
{
if (k == ENTER)
{
doc.InsertEnterAt(enterx, y-1);
return;
}
if (k == KEY_NULL)
{
return;
}
doc.InsertCharAt(x-1, y, k);
return;
}
private:
int enterx;
int x;
int y;
int k;
ECDocument &doc;
};
class EnterCommand : public ECCommand
{
public:
EnterCommand(int xcursor, int ycursor, ECDocument &docIn) : x(xcursor), y(ycursor), doc(docIn)
{
}
void Execute()
{
doc.InsertEnterAt(x, y);
return;
}
void UnExecute()
{
doc.RemoveCharAt(0, y+1);
return;
}
private:
int x;
int y;
ECDocument &doc;
};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ECEditor
ECEditor :: ECEditor()
{
_histCmds = new ECCommandHistory;
StartEditor();
}
ECEditor :: ~ECEditor() {}
void ECEditor :: StartEditor()
{
_window.Attach(this);
_window.Init();
_window.AddRow("");
_maxRowSize = _window.GetColNumInView();
_maxRows = _window.GetRowNumInView();
_doc.SetPageDimensions(_maxRowSize, _maxRows);
_window.Show();
}
void ECEditor :: Update()
{
int key = _window.GetPressedKey();
int x = _window.GetCursorX();
int y = _window.GetCursorY();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Ctrl commands and mouse movement
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (key == CTRL_Q)
{
_window.Quit();
return;
}
if ((1000 <= key) && (key <=1004)) // Arrow keys
{
_doc.MoveCursor(key);
UpdateCursor();
return;
}
if (key == ENTER)
{
Enter(x, y);
_histCmds->EmptyRedo();
UpdateCursor();
UpdateScreen();
return;
}
if (key == BACKSPACE)
{
Backspace(x, y);
_histCmds->EmptyRedo();
UpdateCursor();
UpdateScreen();
return;
}
if (key == CTRL_Z)
{
_histCmds->Undo();
UpdateCursor();
UpdateScreen();
return;
}
if (key == CTRL_Y)
{
_histCmds->Redo();
UpdateCursor();
UpdateScreen();
return;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Text Addition
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if ((32 <= key) && (key <= 126))
{
AddText(x, y, key);
_histCmds->EmptyRedo();
UpdateCursor();
UpdateScreen();
return;
}
}
void ECEditor :: UpdateCursor()
{
int x = _doc.GetXCursor();
int y = _doc.GetYCursor();
_window.SetCursorX(x);
_window.SetCursorY(y);
_window.Refresh();
}
void ECEditor :: Enter(int x, int y)
{
EnterCommand *cmd = new EnterCommand(x, y, _doc);
_histCmds->ExecuteCmd(cmd);
}
void ECEditor :: AddText(int x, int y, int key)
{
InsertCommand *cmd = new InsertCommand(x, y, key, _doc);
_histCmds->ExecuteCmd(cmd);
}
void ECEditor :: Backspace(int x, int y)
{
RemoveCommand *cmd = new RemoveCommand(x, y, _doc);
_histCmds->ExecuteCmd(cmd);
}
void ECEditor :: UpdateScreen()
{
_window.InitRows();
_window.AddRow("");
for (int i = 0; i < _doc.GetDocLen(); i++)
{
_window.AddRow(_doc.GetRowAt(i));
}
_window.Refresh();
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ECTextDocument
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ECDocument :: ECDocument()
{
_document.clear();
ECRow row;
_document.push_back(row);
}
ECDocument :: ~ECDocument()
{
}
void ECDocument :: SetPageDimensions(int x, int y)
{
_colInView = x;
_rowInView = y;
return;
}
int ECDocument :: GetDocLen()
{
return _document.size();
}
int ECDocument :: GetRowSizeAt(int y)
{
return _document[y].GetSize();
}
char ECDocument :: GetCharAt(int x, int y)
{
if (x == 0)
{
if (_ydoc == 0)
{
return KEY_NULL;
}
return ENTER;
}
return _document[y].GetChar(x-1);
}
int ECDocument :: GetXCursor()
{
return _xcursor;
}
int ECDocument :: GetYCursor()
{
return _ycursor;
}
void ECDocument :: MoveCursor(int key)
{
if (key == KEY_NULL)
{
return;
}
if (key == ARROW_LEFT)
{
if (_xcursor > 0)
{
_xcursor -= 1;
return;
}
if (_ycursor > 0)
{
_ycursor -= 1;
_xcursor = GetRowSizeAt(_ydoc);
return;
}
}
if (key == ARROW_RIGHT)
{
int col = GetRowSizeAt(_ydoc);
if (_xcursor < col)
{
_xcursor += 1;
return;
}
int row = GetDocLen();
if (_ycursor < row-1)
{
_ycursor += 1;
_ydoc += 1;
_xcursor = 0;
return;
}
}
if (key == ARROW_DOWN)
{
int row = GetDocLen();
if (_ycursor < row-1)
{
_ycursor += 1;
_ydoc += 1;
int col = GetRowSizeAt(_ydoc);
if (_xcursor > col)
{
_xcursor = col;
}
return;
}
_xcursor = GetRowSizeAt(_ydoc);
return;
}
if (key == ARROW_UP)
{
if (_ycursor > 0)
{
int col = GetRowSizeAt(_ydoc-1);
if (_xcursor > col)
{
_xcursor = col;
}
_ycursor -= 1;
_ydoc -= 1;
return;
}
_xcursor = 0;
return;
}
if (key == ENTER)
{
_xcursor = 0;
_ycursor += 1;
_ydoc += 1;
return;
}
if (key == BACKSPACE)
{
_ycursor -= 1;
_ydoc -= 1;
_xcursor = GetRowSizeAt(_ydoc);
return;
}
}
string ECDocument :: GetRowAt(int y)
{
return _document[y].ShowSelf();
}
void ECDocument :: InsertCharAt(int x, int y, int key)
{
if (x != _xcursor)
{
_xcursor = x;
}
if (y != _ycursor)
{
_ycursor = y;
_ydoc = y;
}
_document[y].AddCharAt(x, key);
if (_document[y].GetSize() >= _colInView)
{
int lasty;
int lastx;
if (_xcursor == _document[y].GetSize() - 1)
{
lasty = _ydoc + 1;
lastx = 0;
}
else
{
lasty = _ydoc;
lastx = _xcursor + 1;
}
string word = _document[y].GetLastWord();
if (lastx == 0)
{
lastx = word.size();
}
MoveWordDown(word);
_xcursor = lastx;
_ydoc = lasty;
_ycursor = lasty;
}
else
{
MoveCursor(ARROW_RIGHT);
}
return;
}
void ECDocument :: RemoveCharAt(int x, int y)
{
if (x != _xcursor)
{
_xcursor = x;
}
if (y != _ycursor)
{
_ycursor = y;
_ydoc = y;
}
int key;
key = _document[y].RemoveCharAt(x);
/*
Okay so we need to do 2 things.
1) If the backspace removes the room for a new word, we have to bring it up a row.
2) If the backspace is the start of an enter, we need to figure out how to do text wrapping (bringing down extra from a line)
*/
if (key != BACKSPACE) // Doing this first, will be opposite of MoveWordDown.
{
// Should be able to check size of first word, without constantly looking through whole row.
// Therefore, row should have an attribute FirstWord, only to be updated if the row is updated before that size.
if (y < GetDocLen()-1)
{
if (_document[y+1].IsFirst())
{
MoveCursor(key);
return;
}
if (_colInView - _document[y].GetSize() > _document[y+1].FirstWord() + 1)
{
int lastx = _xcursor;
int lasty = _ydoc;
MoveWordUp();
_xcursor = lastx;
_ydoc = lasty;
_ycursor = _ydoc;
}
}
MoveCursor(key);
}
else // Should turn this into a function, will be hella complicated.
{
string text = _document[y].ShowSelf();
MoveCursor(BACKSPACE);
_document.erase(_document.begin()+y);
int rowsize = _document[y-1].GetSize();
int finsize = rowsize + text.size();
for (int i = rowsize; i < finsize; i++)
{
_document[y-1].AddCharAt(i, int(text[i - rowsize]));
}
// Need to then take a line thats too long, and move words down until it is okay again. Yikes.
}
return;
}
void ECDocument :: InsertEnterAt(int x, int y)
{
if (x != _xcursor)
{
_xcursor = x;
}
if (y != _ycursor)
{
_ycursor = y;
_ydoc = y;
}
string text = _document[y].AddEnterAt(x); // Get text for next line
ECRow row; // Init a new row
if (y == GetDocLen()-1) // If end of doc, just add the row at the end
{
_document.push_back(row);
_document[y+1].SetFirst(true);
}
else // Else, insert the row
{
_document.insert(_document.begin() + y + 1, row);
_document[y+1].SetFirst(true);
}
for (int i = 0; i < text.size(); i++)
{
_document[y+1].AddCharAt(i, int(text[i]));
}
MoveCursor(ENTER);
return;
}
void ECDocument :: MoveWordDown(string word)
{
_xcursor = 0;
_ycursor += 1;
_ydoc += 1;
if (_ydoc == GetDocLen())
{
// cout << "Entered the end of doc conditional" << endl;
ECRow row;
_document.push_back(row);
for (int i =0; i < word.size(); i++)
{
_document[_ydoc].AddCharAt(i, int(word[i]));
_xcursor += 1;
}
return;
}
if (_document[_ydoc].IsFirst())
{
ECRow row;
_document.insert(_document.begin() + _ydoc, row);
for (int i =0; i < word.size(); i++)
{
_document[_ydoc].AddCharAt(i, int(word[i]));
_xcursor += 1;
}
return;
}
// cout << "The word is : " << word << endl;
// exit(1);
for (int i =0; i < word.size(); i++)
{
_document[_ydoc].AddCharAt(i, int(word[i]));
_xcursor += 1;
}
while (_document[_ydoc].GetSize() >= _colInView)
{
string newWord = _document[_ydoc].GetLastWord();
MoveWordDown(newWord);
}
return;
}
void ECDocument :: MoveWordUp()
{
if (_document[_ydoc+1].IsFirst())
{
return;
}
if(_document[_ydoc].GetSize() == 0)
{
_document.erase(_document.begin()+_ydoc);
}
string word = _document[_ydoc+1].GetFirstWord();
for (int i = 0; i < word.size(); i++)
{
_document[_ydoc].AddCharAt(_document[_ydoc].GetSize(), int(word[i]));
}
if (_ydoc < GetDocLen() - 1)
{
if (_document[_ydoc+1].GetSize() == 0)
{
_document.erase(_document.begin()+_ydoc+1);
}
if (!_document[_ydoc + 1].IsFirst())
{
_ydoc += 1;
if (_colInView - _document[_ydoc].GetSize() > _document[_ydoc+1].FirstWord() + 1)
{
MoveWordUp();
}
}
}
return;
}