Bläddra i källkod

Color range support for labels, Lua syntax highlighting in the IDE

Ivan Safrin 13 år sedan
förälder
incheckning
00108aceb3

+ 16 - 1
Core/Contents/Include/PolyLabel.h

@@ -31,6 +31,14 @@ namespace Polycode {
 
 	class Font;
 
+	class ColorRange {
+		public:
+			ColorRange(Color color, unsigned int rangeStart, unsigned int rangeEnd);
+			Color color;
+			unsigned int rangeStart;
+			unsigned int rangeEnd;			
+	};
+
 	class _PolyExport Label : public Image {
 		public:
 			
@@ -45,13 +53,20 @@ namespace Polycode {
 			Number getTextWidth() const;
 			Number getTextHeight() const;
 		
+			void clearColors();
+			void setColorForRange(Color color, unsigned int rangeStart, unsigned int rangeEnd);
+		
+			Color getColorForIndex(unsigned int index);
+		
 			Font *getFont() const;
 					
 			static const int ANTIALIAS_FULL = 0;
 			static const int ANTIALIAS_NONE = 1;
 			
 		protected:
-
+	
+			std::vector<ColorRange> colorRanges;
+		
 			bool premultiplyAlpha;
 
 			Number currentTextWidth;

+ 37 - 9
Core/Contents/Source/PolyLabel.cpp

@@ -27,6 +27,12 @@ using namespace Polycode;
 
 #define NORMAL_FT_FLAGS FT_LOAD_TARGET_LIGHT
 
+ColorRange::ColorRange(Color color, unsigned int rangeStart, unsigned int rangeEnd) {
+	this->color = color;
+	this->rangeStart = rangeStart;
+	this->rangeEnd = rangeEnd;	
+}
+
 
 Label::Label(Font *font, const String& text, int size, int antiAliasMode, bool premultiplyAlpha) : Image() {
 		setPixelType(Image::IMAGE_RGBA);
@@ -121,6 +127,23 @@ const String& Label::getText() const {
 	return text;
 }
 
+void Label::clearColors() {
+	colorRanges.clear();
+}
+
+void Label::setColorForRange(Color color, unsigned int rangeStart, unsigned int rangeEnd) {
+	colorRanges.push_back(ColorRange(color, rangeStart, rangeEnd));
+}
+
+Color Label::getColorForIndex(unsigned int index) {
+	for(int i=0; i < colorRanges.size(); i++) {
+		if(index >= colorRanges[i].rangeStart && index <= colorRanges[i].rangeEnd) {
+			return colorRanges[i].color;
+		}
+	}
+	return Color(1.0,1.0,1.0,1.0);
+}
+
 void Label::setText(const String& text) {
 //	Logger::logw((char*)text.c_str());
 	
@@ -177,6 +200,8 @@ void Label::setText(const String& text) {
 				FT_Render_Glyph(slot, FT_RENDER_MODE_MONO);
 			break;
 		}
+		
+		Color glyphColor = getColorForIndex(i);
 
 		int lineoffset = ((size-slot->bitmap_top) * (textWidth*4));
 		xoff = ((penX + slot->bitmap_left)*4);
@@ -190,16 +215,19 @@ void Label::setText(const String& text) {
 						int newVal = imageData[xoff+lineoffset+3] + slot->bitmap.buffer[j];
 						if(newVal > 255)
 							newVal = 255;
+							
+						newVal = (int)(((Number)newVal) * glyphColor.a);
+						
 						imageData[xoff+lineoffset+3] = newVal;
 													
 						if(premultiplyAlpha) {
-							imageData[xoff+lineoffset] = (int)(255.0 * ((Number)imageData[xoff+lineoffset+3])/255.0);
-							imageData[xoff+lineoffset+1] =  (int)(255.0 * ((Number)imageData[xoff+lineoffset+3])/255.0);
-							imageData[xoff+lineoffset+2] =  (int)(255.0 * ((Number)imageData[xoff+lineoffset+3])/255.0);
+							imageData[xoff+lineoffset] = (int)((255.0 * glyphColor.r) * ((Number)imageData[xoff+lineoffset+3])/255.0);
+							imageData[xoff+lineoffset+1] =  (int)((255.0 * glyphColor.g) * ((Number)imageData[xoff+lineoffset+3])/255.0);
+							imageData[xoff+lineoffset+2] =  (int)((255.0 * glyphColor.b) * ((Number)imageData[xoff+lineoffset+3])/255.0);
 						} else {
-							imageData[xoff+lineoffset] = 255;
-							imageData[xoff+lineoffset+1] =  255;
-							imageData[xoff+lineoffset+2] =  255;						
+							imageData[xoff+lineoffset] = (int)(255.0 * glyphColor.r);
+							imageData[xoff+lineoffset+1] =  (int)(255.0 * glyphColor.g);
+							imageData[xoff+lineoffset+2] =  (int)(255.0 * glyphColor.b);						
 						} 	
 							
 						xoff += 4;
@@ -212,9 +240,9 @@ void Label::setText(const String& text) {
 					unsigned char *bptr =  src;
 					for(int k=0; k < slot->bitmap.width ; k++){					
 						if (k%8==0){ b = (*bptr++);}
-						imageData[xoff+lineoffset] = 255;
-						imageData[xoff+lineoffset+1] =  255;
-						imageData[xoff+lineoffset+2] =  255;
+						imageData[xoff+lineoffset] = (int)(255.0 * glyphColor.r);
+						imageData[xoff+lineoffset+1] =  (int)(255.0 * glyphColor.g);
+						imageData[xoff+lineoffset+2] =  (int)(255.0 * glyphColor.b);
 						imageData[xoff+lineoffset+3] =  b&0x80 ? 255 : 0;
 						xoff += 4;
 						b <<= 1;

+ 1 - 1
IDE/Contents/Resources/UIThemes/default/theme.xml

@@ -5,7 +5,7 @@
 	<uiTextInputFontNameMultiLine>mono</uiTextInputFontNameMultiLine>
 	<uiDefaultFontSize>11</uiDefaultFontSize>
 	<uiTextInputFontSize>11</uiTextInputFontSize>
-	<uiTextInputFontSizeMultiline>11</uiTextInputFontSizeMultiline>	
+	<uiTextInputFontSizeMultiline>12</uiTextInputFontSizeMultiline>	
 	<uiTreeArrowIconImage>arrowIcon.png</uiTreeArrowIconImage>
 	<uiTreeCellHeight>20</uiTreeCellHeight>
 	<uiTreeCellPadding>4</uiTreeCellPadding>

+ 3 - 1
IDE/Contents/Source/PolycodeTextEditor.cpp

@@ -35,7 +35,7 @@ PolycodeSyntaxHighlighter::PolycodeSyntaxHighlighter(String extension) {
 //	String separators = " ;()\t\n=+-/\\'\"";	
 //	String keywords = "true,false,";
 	
-	separators = String(" ; ( ) \t \n = + - / \\ ' \"").split(" ");
+	separators = String(" ; . , : ( ) \t \n = + - / \\ ' \"").split(" ");
 	separators.push_back(" ");
 	
 	keywords = String("true false class self break do end else elseif function if local nil not or repeat return then until while").split(" ");
@@ -60,6 +60,8 @@ std::vector<SyntaxHighlightToken> PolycodeSyntaxHighlighter::parseText(String te
 std::vector<SyntaxHighlightToken> PolycodeSyntaxHighlighter::parseLua(String text) {
 	std::vector<SyntaxHighlightToken> tokens;
 	
+	text = text+"\n";
+	
 	const int MODE_GENERAL = 0;
 	const int MODE_COMMENT = 1;
 	const int MODE_STRING = 2;

+ 36 - 0
Modules/Contents/UI/Source/PolyUITextInput.cpp

@@ -310,6 +310,42 @@ void UITextInput::changedText() {
 
 	if(syntaxHighliter) {
 		std::vector<SyntaxHighlightToken> tokens = syntaxHighliter->parseText(getText());
+		
+		for(int i=0; i < lines.size(); i++) {
+			lines[i]->getLabel()->clearColors();
+		}
+		
+		int lineIndex = 0;
+		int rangeStart = 0;
+		int rangeEnd = 0;
+				
+		for(int i=0; i < tokens.size(); i++) {			
+			if(tokens[i].text == "\n") {
+				lineIndex++;
+				rangeStart = 0;
+				rangeEnd = 0;
+			} else {
+			
+				if(lineIndex < lines.size()) {
+					int textLength = tokens[i].text.length();
+					if(tokens[i].text.length() > 1) {
+						rangeEnd = rangeStart + textLength-1;
+						lines[lineIndex]->getLabel()->setColorForRange(tokens[i].color, rangeStart, rangeEnd);	
+						rangeStart = rangeStart + textLength; 
+					} else {
+						rangeEnd = rangeStart;
+						lines[lineIndex]->getLabel()->setColorForRange(tokens[i].color, rangeStart, rangeEnd);	
+						rangeStart++;
+					}				
+				}
+			}
+		}
+		
+		for(int i=0; i < lines.size(); i++) {
+			lines[i]->setText(lines[i]->getText());
+			lines[i]->setColor(1.0, 1.0, 1.0, 1.0);
+		}
+		
 	}
 
 	dispatchEvent(new UIEvent(), UIEvent::CHANGE_EVENT);