?? textbox.cpp
字號:
#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 + -