Просмотр исходного кода

Line number support in UITextInput, Monokai syntax theme

Ivan Safrin 13 лет назад
Родитель
Сommit
3977a25908

+ 1 - 0
IDE/Contents/Include/PolycodeTextEditor.h

@@ -35,6 +35,7 @@ class SyntaxHighlightTheme {
 		Color bgColor;
 		Color selectionColor;
 		Color cursorColor;
+		Color lineNumberColor;
 		bool useStrongHinting;
 		Color colors[8];
 };

+ 1 - 0
IDE/Contents/Resources/SyntaxThemes/monokai.xml

@@ -3,6 +3,7 @@
 	<bgColor r="39" g="40" b="34"/>
 	<cursorColor r="255" g="255" b="255"/>
 	<selectionColor r="51" g="50" b="54"/>
+	<lineNumberColor r="70" g="60" b="50"/>
 	<textColors>
 		<color r="233" g="226" b="222"/>
 		<color r="117" g="113" b="94"/>	

+ 13 - 0
IDE/Contents/Source/PolycodeTextEditor.cpp

@@ -66,6 +66,16 @@ void SyntaxHighlightTheme::loadFromFile(String themeName) {
 				selectionColor.setColorRGB(r->intVal, g->intVal, b->intVal);
 			}		
 		}
+		
+		ObjectEntry *lineNumberColorEntry = themeObject.root["lineNumberColor"];		
+		if(lineNumberColorEntry) {
+			ObjectEntry *r = (*lineNumberColorEntry)["r"];
+			ObjectEntry *g = (*lineNumberColorEntry)["g"];
+			ObjectEntry *b = (*lineNumberColorEntry)["b"];
+			if(r && g && b) {
+				lineNumberColor.setColorRGB(r->intVal, g->intVal, b->intVal);
+			}		
+		}		
 			
 		ObjectEntry *textColors = themeObject.root["textColors"];
 		if(textColors) {
@@ -267,6 +277,9 @@ bool PolycodeTextEditor::openFile(OSFileEntry filePath) {
 	textInput->setCursorColor(globalSyntaxTheme->cursorColor);
 	textInput->setSelectionColor(globalSyntaxTheme->selectionColor);
 	textInput->useStrongHinting = globalSyntaxTheme->useStrongHinting;
+	textInput->setLineNumberColor(globalSyntaxTheme->lineNumberColor);
+	textInput->enableLineNumbers(true);
+	
 	
 	findBar = new FindBar();
 	findBar->visible = false;

+ 16 - 1
Modules/Contents/UI/Include/PolyUITextInput.h

@@ -102,10 +102,13 @@ namespace Polycode {
 			void Copy();
 			void Paste();
 			
+			void enableLineNumbers(bool val);
+			
 			void setBackgroundColor(Color color);
 			void setSelectionColor(Color color);
 			void setCursorColor(Color color);
 			void setTextColor(Color color);
+			void setLineNumberColor(Color color);
 			
 			void replaceAll(String what, String withWhat);
 			
@@ -134,7 +137,14 @@ namespace Polycode {
 		
 		protected:
 		
+			ScreenEntity *lineNumberAnchor;
+		
+			void renumberLines();
+		
+			bool lineNumbersEnabled;
+		
 			Color textColor;
+			Color lineNumberColor;
 				
 			void setUndoState(UITextInputUndoState state);
 			void saveUndoState();
@@ -167,7 +177,11 @@ namespace Polycode {
 			int selectionTop;
 			int selectionBottom;
 			int selectionL;
-			int selectionR;		
+			int selectionR;
+			
+			ScreenShape *lineNumberBg;
+			
+			int decoratorOffset;
 		
 			bool settingText;
 		
@@ -211,6 +225,7 @@ namespace Polycode {
 			int lineOffset;
 			ScreenLabel *currentLine;		
 			vector<ScreenLabel*> lines;
+			vector<ScreenLabel*> numberLines;			
 			
 	};
 }

+ 88 - 9
Modules/Contents/UI/Source/PolyUITextInput.cpp

@@ -35,12 +35,16 @@ UITextInput::UITextInput(bool multiLine, Number width, Number height) : UIElemen
 	processInputEvents = true;
 	isNumberOnly = false;
 	
+	decoratorOffset = 0;
+	
 	useStrongHinting = false;
 	
 	draggingSelection = false;
 	hasSelection = false;
 	doSelectToCaret = false;
 	
+	lineNumbersEnabled = false;
+	
 	caretPosition = 0;
 	caretImagePosition = 0;
 	
@@ -89,6 +93,22 @@ UITextInput::UITextInput(bool multiLine, Number width, Number height) : UIElemen
 	
 	addChild(inputRect);		
 	
+	if(multiLine) {
+		lineNumberBg = new ScreenShape(ScreenShape::SHAPE_RECT, 1,1);
+		lineNumberBg->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
+		lineNumberBg->setColor(0.0, 0.0, 0.0, 0.3);
+		addChild(lineNumberBg);
+		lineNumberBg->visible = false;
+		
+		lineNumberAnchor = new ScreenEntity();
+		linesContainer->addChild(lineNumberAnchor);
+		
+	} else {
+		lineNumberBg = NULL;
+		lineNumberAnchor = NULL;
+	}
+
+	
 	inputRect->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
 	inputRect->addEventListener(this, InputEvent::EVENT_MOUSEUP);	
 	inputRect->addEventListener(this, InputEvent::EVENT_DOUBLECLICK);		
@@ -144,7 +164,7 @@ UITextInput::UITextInput(bool multiLine, Number width, Number height) : UIElemen
 		addChild(linesContainer);
 		enableScissor = true;
 	}
-	
+		
 	undoStateIndex = 0;
 	maxRedoIndex = 0;
 	
@@ -233,7 +253,7 @@ void UITextInput::setSelection(int lineStart, int lineEnd, int colStart, int col
 	}
 
 	selectorRectTop->setScale(topSize, topHeight);
-	selectorRectTop->setPosition(topX + padding + (topSize/2.0), padding + (lineStart * (lineHeight+lineSpacing)) + (topHeight/2.0));
+	selectorRectTop->setPosition(decoratorOffset + topX + padding + (topSize/2.0), padding + (lineStart * (lineHeight+lineSpacing)) + (topHeight/2.0));
 	
 	if(lineEnd > lineStart && lineEnd < lines.size()) {
 		ScreenLabel *bottomLine = lines[lineEnd];	
@@ -243,7 +263,7 @@ void UITextInput::setSelection(int lineStart, int lineEnd, int colStart, int col
 			bottomSize = this->width-padding;
 		Number bottomHeight = lineHeight+lineSpacing;
 		selectorRectBottom->setScale(bottomSize, bottomHeight);
-		selectorRectBottom->setPosition(padding + (bottomSize/2.0), padding + (lineEnd * (lineHeight+lineSpacing)) + (bottomHeight/2.0));
+		selectorRectBottom->setPosition(decoratorOffset + padding + (bottomSize/2.0), padding + (lineEnd * (lineHeight+lineSpacing)) + (bottomHeight/2.0));
 		
 		if(lineEnd != lineStart+1) {
 			// need filler
@@ -254,7 +274,7 @@ void UITextInput::setSelection(int lineStart, int lineEnd, int colStart, int col
 				midHeight += lineHeight+lineSpacing;
 			}
 			selectorRectMiddle->setScale(midSize, midHeight);
-			selectorRectMiddle->setPosition(padding + (midSize/2.0), padding + ((lineStart+1) * (lineHeight+lineSpacing)) + (midHeight/2.0));										
+			selectorRectMiddle->setPosition(decoratorOffset + padding + (midSize/2.0), padding + ((lineStart+1) * (lineHeight+lineSpacing)) + (midHeight/2.0));										
 			
 		}
 		
@@ -399,6 +419,10 @@ void UITextInput::Resize(Number width, Number height) {
 	if(multiLine) {
 		inputRect->setHitbox(width - scrollContainer->getVScrollWidth(), height);
 	}
+	
+	if(multiLine && lineNumbersEnabled) {
+		lineNumberBg->setShapeSize(decoratorOffset, height);
+	}
 
 	if(scrollContainer) {
 		scrollContainer->Resize(width, height);
@@ -414,10 +438,21 @@ int UITextInput::insertLine(bool after) {
 		aaMode = Label::ANTIALIAS_STRONG;
 	}
 
+	if(multiLine) {
+		ScreenLabel *newNumberLine = new ScreenLabel(L"", fontSize, fontName, aaMode);
+		newNumberLine->color = lineNumberColor;
+		lineNumberAnchor->addChild(newNumberLine);
+		numberLines.push_back(newNumberLine);		
+		
+		if(!lineNumbersEnabled) {
+			newNumberLine->visible = false;
+		}
+	}
+	
 	ScreenLabel *newLine = new ScreenLabel(L"", fontSize, fontName, aaMode);
 	newLine->color = textColor;
 	lineHeight = newLine->getHeight();
-	linesContainer->addChild(newLine);
+	linesContainer->addChild(newLine);	
 	
 	if(after) {	
 		
@@ -442,19 +477,55 @@ int UITextInput::insertLine(bool after) {
 		lineOffset = lineOffset + 1;	
 		lines.insert(it,newLine);
 		
+		renumberLines();
 		restructLines();
 	} else {	
 		// do we even need that? I don't think so.
 	}	
-		
+	
 	changedText();
 	return 1;	
 }
 
+void UITextInput::enableLineNumbers(bool val) {
+	lineNumbersEnabled = val;
+	lineNumberBg->visible = lineNumbersEnabled;
+	restructLines();
+}
+
+void UITextInput::renumberLines() {
+	if(!multiLine)
+		return;
+		
+	decoratorOffset = 0;	
+	if(multiLine) {
+	for(int i=0; i < numberLines.size(); i++) {
+		if(lineNumbersEnabled) {
+			numberLines[i]->setText(String::IntToString(i+1));		
+			int textWidth = ceil(numberLines[i]->getLabel()->getTextWidth());			
+			numberLines[i]->setPosition(-textWidth,padding + (i*(lineHeight+lineSpacing)),0.0f);		
+			if(textWidth > decoratorOffset - 10) {
+				decoratorOffset = textWidth + 10;
+			}
+			numberLines[i]->visible = true;
+		} else {
+			numberLines[i]->visible = false;		
+		}
+	}
+	}
+	
+	lineNumberAnchor->setPositionX(padding+decoratorOffset - 10);
+	
+}
+
 void UITextInput::restructLines() {
 
 	for(int i=0; i < lines.size(); i++) {
-		lines[i]->setPosition(padding,padding + (i*(lineHeight+lineSpacing)),0.0f);		
+		lines[i]->setPosition(decoratorOffset + padding,padding + (i*(lineHeight+lineSpacing)),0.0f);			
+	}
+	
+	if(multiLine && lineNumbersEnabled) {
+		lineNumberBg->setShapeSize(decoratorOffset, height);
 	}
 	
 	if(scrollContainer) {
@@ -704,7 +775,7 @@ void UITextInput::findCurrent() {
 
 void UITextInput::setCaretToMouse(Number x, Number y) {
 	clearSelection();
-	x -= (padding);
+	x -= (padding) + decoratorOffset;
 	y -= padding;
 	//if(lines.size() > 1) {
 		lineOffset = y  / (lineHeight+lineSpacing);
@@ -752,6 +823,7 @@ void UITextInput::removeLine(ScreenLabel *line) {
 	}
 	linesContainer->removeChild(line);
 	linesToDelete.push_back(line);
+	renumberLines();
 	restructLines();
 	changedText();
 }
@@ -850,6 +922,13 @@ void UITextInput::setBackgroundColor(Color color) {
 	inputRect->color = color;
 }
 
+void UITextInput::setLineNumberColor(Color color) {
+	lineNumberColor = color;
+	for(int i=0; i < numberLines.size(); i++) {
+		numberLines[i]->color = lineNumberColor;
+	}	
+}
+
 void UITextInput::setTextColor(Color color) {
 	textColor = color;
 	for(int i=0; i < lines.size(); i++) {
@@ -1241,7 +1320,7 @@ void UITextInput::Update() {
 	if(hasSelection) {
 		blinkerRect->visible = false;
 	}
-	blinkerRect->setPosition(caretImagePosition + 1,currentLine->getPosition2D().y+1);
+	blinkerRect->setPosition(decoratorOffset + caretImagePosition + 1,currentLine->getPosition2D().y+1);
 	if(hasFocus) {
 //		inputRect->setStrokeColor(1.0f, 1.0f, 1.0f, 0.25f);	
 	} else {