⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textbox.cpp

📁 SimpleGraphicOperatingSystem 32位图形化操作系统 多进程 支持FAT32 详见www.sgos.net.cn
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <osdef.h>//WM_**
#include <System.h>
#include <Api.h>	//Sgos api

namespace System{
	class MyVScroll: public VScrollBar{
    private:
        TextBox* parent;
    public:
        MyVScroll::MyVScroll( TextBox* p, int style ):
            VScrollBar( p, style ){
            parent = p;
        }
        virtual int MyVScroll::OnChange( int v ){
            parent->SetVisualPosition( -1, v );
            VScrollBar::OnChange(v);
        }
    };

	int TextBox::SetVisualPosition( int x, int y ){
		if(x<0)x=0;
		if(y<0)y=0;
		if(!(style&TEXTBOX_NOVSCROLLBAR))
			if(y>vScroll->VScrollBar::Max())y=vScroll->VScrollBar::Max();
		vX = x;
		vY = y;
		ReloadChars();
		SetSelLength(selLength);
		DrawChars();
		if(!(style&TEXTBOX_NOVSCROLLBAR))
			vScroll->SetValue( vY );
		return true;
	}

	int TextBox::OnSize( int w, int h ){
		Width = w;
		Height = h;
		left = midSpace;
		top = midSpace;
		if( style&TEXTBOX_NOVSCROLLBAR )
			right = w-midSpace;
		else
			right = w-vScroll->BaseWindow::Width();
		bottom = h-midSpace;
		if( bottom<=top||right<=left )
		{
			delete this;
			return 0;
		}
		rowChars = (right-left)/cw;
		colChars = (bottom-top)/ch;
		if(rowChars<1)rowChars=1;
		if(colChars<1)colChars=1;
		if( style&TEXTBOX_NOAUTONEXTLINE )	//没有自动换行
		{
			maxCharPerLine = 8192;
		}else{
			maxCharPerLine = rowChars;
		}
		delete[] chars;
		chars = new _Char[rowChars*colChars];
		if(!(style&TEXTBOX_NOVSCROLLBAR)){
			vScroll->Move( Width-vScroll->BaseWindow::Width(), 0, vScroll->BaseWindow::Width(), Height );
			SetScrollBar();
		}
		ReloadChars();
		DrawChars();

		BaseWindow::OnSize(w,h);
	}

	TextBox::~TextBox(){
		if(vScroll)
			delete vScroll;
	}

	TextBox::TextBox( BaseWindow* parent, string text, int style ):
		BaseWindow( parent, text, style )
	{
	    //文本框样式
		winStyle.active.backColor=Bitmap::MakeColor(99,99,99);	//激活时窗体背景颜色
		//获取字符长宽占多少象素
		Bitmap::CalculateTextSize( "a", 1, FONT_MINI_SIZE, 0, &cw, &ch );
		ch+=1;	//为了好看
		midSpace = 4;
		selStart=0;
		bShift=false;
		bCatched=false;
		selLength = 0;
		this->style = style;
		type = TypeTextBox;
        //默认大小
		Width = 320;
		Height = 200;

		if(!(style&TEXTBOX_NOVSCROLLBAR)){
			this->style|=TEXTBOX_MUTILINE;
			vScroll = new MyVScroll( this, 0 );
			vScroll->Move( Width-vScroll->BaseWindow::Width(), 0, vScroll->BaseWindow::Width(), Height );
			vScroll->Show();
		}
		SetSize( Width, Height );

		SetText(text);
		SetSelStart(0);
	}

	//Count how many lines there are
	int TextBox::GetTextLines(){
		int i,r,c;
		r=c=0;
		for(i=0;i<strContent.Length();i++){
			c++;
			if(c==maxCharPerLine-1){
				if((unsigned char)strContent[i]>0xA0){
					r++;
					c=0;
					i++;
					continue;
				}
			}
			if(strContent[i]=='\r'||strContent[i]=='\n'||c>=maxCharPerLine){
				r++;
				c=0;
				if( strContent[i]=='\r' && strContent[i+1]=='\n' ) i++;
			}
		}
		return r;
	}

	bool TextBox::HasWordFlag(int pos){
		int i;
		bool bigWord = 0;
		for(i=0;i<strContent.Length();i++){
			if( (unsigned char)strContent[i]>0xA0 )
				bigWord=!bigWord;
			if( i==pos ){
				return bigWord;
			}
		}
		return false;
	}

	//the char position of row*,col*
	int TextBox::GetCharPos(int row, int col){
		int i,r,c;
		r=c=0;
		bool bigWord = 0;
		for(i=0;i<strContent.Length();i++){
			if( row==r&&col==c ){
				return i;
			}
			if( (unsigned char)strContent[i]>0xA0 )
				bigWord=!bigWord;
			c++;
			if(strContent[i]=='\n'||strContent[i]=='\r'||c>=maxCharPerLine){
				if(bigWord){
					bigWord=0;
					i--;
				}
				r++;
				c=0;
				if( strContent[i]=='\r' && strContent[i+1]=='\n' ) i++;
			}
		}
		return -1;
	}

	int TextBox::GetRowFromPos(int pos)
	{
		int i,r,c;
		r=c=0;
		for(i=0;i<strContent.Length();i++){
			c++;
			if(i==pos){
				break;
			}
			if(c==maxCharPerLine-1){
				if((unsigned char)strContent[i]>0xA0){
					r++;
					c=0;
					i++;
					continue;
				}
			}
			if(strContent[i]=='\n'||strContent[i]=='\r'||c>=maxCharPerLine){
				r++;
				c=0;
				if( strContent[i]=='\r' && strContent[i+1]=='\n' ) i++;
			}
		}
		return r;
	}

	int TextBox::RemoveChar(_Char* chr)
	{
		if( (chr->wordFlag&&!EqualChar((chr+1)->value,' '))||!EqualChar(chr->value,' ')||chr->selected ){
			chr->dirty=true;
		}
		chr->value=0;
		chr->wordFlag=0;
		chr->pos=-1;
		chr->selected=false;
	}

	int TextBox::EqualChar(char a, char b ){
		if( (a==b)||
				((a==' '||a=='\n'||a=='\r'||a=='\0') &&
					(b==' '||b=='\n'||b=='\r'||b=='\0')) )
		{
			return true;
		}
		return false;
	}

	int TextBox::ReloadChars(){
		int c,r;
		int p, endline;
		bool bigWord = 0;
		for(r=0;r<colChars;r++){
			p = GetCharPos( vY+r, 0 );
			endline=false;
			for(c=0;c<rowChars;c++)
			{
				_Char* chr = &chars[r*rowChars+c];
				chr->wordFlag=0;
				//如果文本已结束
				if( p<0 ){
					RemoveChar(chr);
					chr->pos=p;
				}else{
					if( (unsigned char)strContent[p]>0xA0 )
						bigWord=!bigWord;
					if( c==rowChars-1 && bigWord ){
						RemoveChar(chr);
						chr->pos=p;
						bigWord=0;
					}else{
						if(bigWord)
							chr->wordFlag=1;

						if( (chr->wordFlag&&!EqualChar((chr+1)->value,strContent[p+1]))||!EqualChar(chr->value,strContent[p]) ){
							chr->dirty=true;
						}

						chr->pos=p;
						chr->value=strContent[p];
						//取下一个字符
						if(!endline){
							p++;
							if(chr->value=='\0'||chr->value=='\r'||chr->value=='\n'){
								endline=true;
								p--;
							}
						}else{
							chr->value=0;
						}
					}
				}
			}
		}
	}

	int TextBox::DrawChars(){
		//文字输出
		int textColor = winStyle.active.textColor, backColor;
		int boxw = right-left;
		char buf[3]={0,0,0};
		int r, c, x, y, dirty,n;
		Rect rect;
		for(r=0;r<colChars;r++){
			dirty=false;
			for(c=0;c<rowChars;c++)
			{
				n=r*rowChars+c;
				if(chars[n].dirty){
					buf[0]=chars[n].value;
					x = left+c*cw;
					y = top+r*ch;
					if(!dirty){
						dirty=true;
					}
					if(chars[n].selected){
						bitmap->BackColor=winStyle.active.backColor;	//choose
					}else{
						bitmap->BackColor=winStyle.inactive.backColor;
					}
					if( (unsigned char)buf[0]>0xA0 ){
						buf[1]=chars[n+1].value;
						if( (unsigned char)buf[1]>0xA0 ){
							Bitmap::DrawText( bitmap, buf, 2, x, y, FONT_MINI_SIZE, textColor, TEXT_BACKCOLOR );
							chars[n].dirty =
							chars[n+1].dirty = false;
							c++;
						}
					}else{
						if( buf[0]=='\n'||buf[0]=='\r'||buf[0]=='\t' ){
							buf[0]=' ';
						}
						buf[1]=0;
						Bitmap::DrawText( bitmap, buf, 1, x, y, FONT_MINI_SIZE, textColor, TEXT_BACKCOLOR );
						chars[n].dirty = false;
					}
					if((chars[n].value)&&chars[n].pos==selStart|| selStartChar==&chars[n]){
							DrawCursor(x,y);
					}
				}
			}
			//we refresh a line

			if(dirty){
				rect.left = left;
				rect.top = y;
				rect.bottom = y+ch;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -