0
votes

I am nearing completing the text box for my text editor besides selection and a few bugs with the text cursor. I have to implement it from scratch, because the other libraries do not suit the design needs for my editor. Every time the user completes a line and starts backspacing on the next line, the cursor and the text are not positioned properly when the user starts typing (the cursor is not on the right line). The gap becomes even more significant when the user keeps does this over and over again.

enter image description here

You can clearly see that the cursor (light blue) and the text are not aligned properly. I have attached the code only relevant to this problem. Sorry if the text box is not in optimal positioning, as I have transferred the code from my text editor to a degraded version for this problem.

What I think the culprit is: After a couple of hours, I found that the cursor position is dependent upon the line and column (as indicated on the labels) - I have not attached the labels to the example in this problem. The line shows 2, but it is supposed to be 1. When the column is 1 and the user backspaces, the line is supposed to decrease by 1 and the column set to the length of the previous line.

If you have any questions, I'd be more than happy to answer them. Because the code was complicated to transfer, a lot of it won't work properly (having the cursor move horizontally as the user types) but I think's it is good enough to solve the problem.

How to reach the problem:

  1. Type some text in the first line
  2. Hit enter
  3. Try backspacing

Here is the text box code in Processing Java:

// Content
String content = "";
String[] adjustedLines = {
};

// Current position
int row = 1;
int line = 1;
int column = 1;

// Cursor length
float cursorLength = 12;

// Whether line has been subtracted and readjustment to text has been completed
boolean lineSubtracted = false;

// Positions of scrollbar
float cursorX = width/5 + 55;
float cursorY = 55;

void setup()
{
  // Background and size
  background(0);
  size(1500, 700);
}

// Create set of line numbers given starting number and number of lines
void createLineNumbers(int startingNumber, int numberOfLines)
{
  textAlign(LEFT);
  String lineText = "";
  textLeading(22);

  for (int i = startingNumber; i <= startingNumber + numberOfLines; i++)
  {
    lineText += (str(i) + "\n");
  }

  fill(200);
  text(lineText, width/5 + 12.5, 75);
  textAlign(CENTER);
}

void draw()
{
  background(0);

  // Update cursor position
  cursorX = width/5 + 55;
  cursorY = 55;

  textAlign(CENTER);

  // Text Box
  fill(80);
  rect(width/5, 55, width*4/5, height-55);

  textAlign(LEFT);
  textLeading(22);
  fill(255);

  String[] contentLines = content.split("\n");
  String display = "";
  int lineDifference = 0;

  display = content;
  text(display, width/5+55, 75);

  // Line Numbers
  textAlign(CENTER);
  fill(240);

  createLineNumbers(1 + lineDifference, line + lineDifference);
  cursorY = 55 + 22 * line;

  textAlign(RIGHT);

  // Cursor
  stroke(149, 203, 250);
  strokeWeight(4);
  line(cursorX, cursorY, cursorX - cursorLength, cursorY);
  noStroke();

  textAlign(CENTER);
}

// Updates content and locations from user typing
void keyPressed()
{
  String[] allLines = content.split("(?<=\n)");
  boolean willPrint = false;

  if (key == BACKSPACE)
  {
    if (column <= 1)
    {
      if (line > 1)
      {
        line--;
        lineSubtracted = true;
        finished = false;
      }

      column = 2;

      if (lineSubtracted == true && allLines[allLines.length - 1].length() > 1 && allLines.length > 1)
      {
        column = allLines[allLines.length - 2].length();
      }
    }

    if (content.length() > 0)
    {
      content = content.substring(0, content.length() - 1);
    }

    column--;
  } else if (key == TAB)
  {
    column += 4;
    content += "    ";
  } else
  {
    if (key == ENTER)
    {
      line++;
      column = 0;
    } else if (lineSubtracted == true && finished == false && line > 1)
    {
      if (line == allLines.length)
      {
        content = content.substring(0, content.length() - 1);
      }

      finished = true;
    }

    content += key;

    column++;
  }

  column = allLines[allLines.length - 1].length();
}
1
Why don't you just use a gui library like G4P or ControlP5? - Kevin Workman
@KevinWorkman The libraries don't have the flat, minimalist design I wan to achieve, and I really want to make that design so I unfortunately can't use that. Could you take a look at the problem though? The code isn't exaclty too long. Thanks. If you want you can point me out on the logic for adding and deleting based on key presses. I really want to make this project happen. - Henry Zhu
With the code you posted, the blue line never seems to move to the left or the right. "Don't reinvent the wheel" is pretty good advice. - Kevin Workman
@Workman The code I posted is not designed to move left or right. The code I posted is only tailored to the problem I have mentioned above, which is that the cursor does not go to the previous line when the user hits enter after a line, and starts backspacing. - Henry Zhu
@KevinWorkman I also don't think ControlP5 has a multiline text field . - Henry Zhu

1 Answers

1
votes

For what it's worth, you're jumping through a lot of hoops just to display some editable text. Here is a simplified example that makes Processing do the work for you:

String text = "";
String cursor = "_";

boolean blink = true;

void setup() {
  size(500, 500);
}

void draw() {

  if(frameCount % 30 == 0){
    blink = !blink;
  }

  background(0);

  if(blink){
    text(text, 100, 100, 200, 200);
  }
  else{
    text(text+cursor, 100, 100, 200, 200);
  }
}

void keyPressed()
{
  if (key == BACKSPACE)
  {
    if (text.length() > 0) {
      text = text.substring(0, text.length()-1);
    }
  } else {
    text += key;
  }
}