예제 #1
0
파일: TextEdit.cpp 프로젝트: Esum/gemrb
/** Special Key Press */
bool TextEdit::OnSpecialKeyPress(unsigned char Key)
{
	MarkDirty();
	switch (Key) {
		case GEM_HOME:
			CurPos = 0;
			break;
		case GEM_END:
			CurPos = Text.length();
			break;
		case GEM_LEFT:
			if (CurPos > 0)
				CurPos--;
			break;
		case GEM_RIGHT:
			if (CurPos < Text.length()) {
				CurPos++;
			}
			break;
		case GEM_DELETE:
			if (CurPos < Text.length()) {
				Text.erase(CurPos, 1);
			}
			break;		
		case GEM_BACKSP:
			if (CurPos != 0) {
				Text.erase(--CurPos, 1);
			}
			break;
		case GEM_RETURN:
			RunEventHandler( EditOnDone );
	}
	RunEventHandler( EditOnChange );
	return true;
}
예제 #2
0
/** Mouse Over Event */
void Slider::OnMouseOver(unsigned short x, unsigned short /*y*/)
{
	Changed = true;
	unsigned int oldPos = Pos;
	if (State == IE_GUI_SLIDER_GRABBEDKNOB) {
		int mx = KnobXPos;
		int xmx = x - mx;
		if (x < mx) {
			SetPosition( 0 );
			if (oldPos != Pos) {
				RunEventHandler( SliderOnChange );
			}
			return;
		}
		int befst = xmx / KnobStep;
		if (befst >= KnobStepsCount) {
			SetPosition( KnobStepsCount - 1 );
			if (oldPos != Pos) {
				RunEventHandler( SliderOnChange );
			}
			return;
		}
		short aftst = befst + KnobStep;
		if (( xmx - ( befst * KnobStep ) ) < ( ( aftst * KnobStep ) - xmx )) {
			SetPosition( befst );
		} else {
			SetPosition( aftst );
		}
		if (oldPos != Pos) {
			RunEventHandler( SliderOnChange );
		}
	}
}
예제 #3
0
/** Mouse Over Event */
void WorldMapControl::OnMouseOver(unsigned short x, unsigned short y)
{
	WorldMap* worldmap = core->GetWorldMap();
	lastCursor = IE_CURSOR_GRAB;

	if (MouseIsDown) {
		AdjustScrolling(lastMouseX-x, lastMouseY-y);
	}

	lastMouseX = x;
	lastMouseY = y;

	if (Value!=(ieDword) -1) {
		x =(ieWord) (x + ScrollX);
		y =(ieWord) (y + ScrollY);

		WMPAreaEntry *oldArea = Area;
		Area = NULL;

		unsigned int i;
		unsigned int ec = worldmap->GetEntryCount();
		for (i=0;i<ec;i++) {
			WMPAreaEntry *ae = worldmap->GetEntry(i);

			if ( (ae->GetAreaStatus() & WMP_ENTRY_WALKABLE)!=WMP_ENTRY_WALKABLE) {
				continue; //invisible or inaccessible
			}

			Sprite2D *icon=ae->GetMapIcon(worldmap->bam);
			int h=0, w=0, iconx=0, icony=0;
			if (icon) {
				h=icon->Height;
				w=icon->Width;
				iconx = icon->XPos;
				icony = icon->YPos;
				core->GetVideoDriver()->FreeSprite( icon );
			}
			if (ftext && ae->GetCaption()) {
				int tw = ftext->CalcStringWidth( (unsigned char*)ae->GetCaption() ) + 5;
				int th = ftext->maxHeight;
				if(h<th)
					h=th;
				if(w<tw)
					w=tw;
			}
			if (ae->X - iconx > x) continue;
			if (ae->X - iconx + w < x) continue;
			if (ae->Y - icony > y) continue;
			if (ae->Y - icony + h < y) continue;
			lastCursor = IE_CURSOR_NORMAL;
			Area=ae;
			if(oldArea!=ae) {
				RunEventHandler(WorldMapControlOnEnter);
			}
			break;
		}
	}

	Owner->Cursor = lastCursor;
}
예제 #4
0
//setting up the textarea for smooth scrolling, the first
//TEXTAREA_OUTOFTEXT callback is called automatically
void TextArea::SetupScroll(unsigned long tck)
{
	SetPreservedRow(0);
	smooth = ftext->maxHeight;
	startrow = 0;
	ticks = tck;
	//clearing the textarea
	Clear();
	unsigned int i = (unsigned int) (Height/smooth);
	while (i--) {
		char *str = (char *) malloc(1);
		str[0]=0;
		lines.push_back(str);
		lrows.push_back(0);
	}
	i = (unsigned int) lines.size();
	Flags |= IE_GUI_TEXTAREA_SMOOTHSCROLL;
	GetTime( starttime );
	if (RunEventHandler( TextAreaOutOfText )) {
		//event handler destructed this object?
		return;
	}
	if (i==lines.size()) {
		ResetEventHandler( TextAreaOutOfText );
		return;
	}
	//recalculates rows
	AppendText("\n",-1);
}
예제 #5
0
/** Mouse Button Up */
void TextArea::OnMouseUp(unsigned short x, unsigned short y, unsigned short /*Button*/,
	unsigned short /*Mod*/)
{
	if (( x <= Width ) && ( y <= ( Height - 5 ) ) && ( seltext != -1 )) {
		Value = (unsigned int) seltext;
		Changed = true;
		if (strnicmp( lines[seltext], "[s=", 3 ) == 0) {
			if (minrow > seltext)
				return;
			int idx;
			sscanf( lines[seltext], "[s=%d,", &idx );
			GameControl* gc = core->GetGameControl();
			if (gc && (gc->GetDialogueFlags()&DF_IN_DIALOG) ) {
				if (idx==-1) {
					//this kills this object, don't use any more data!
					gc->EndDialog();
					return;
				}
				gc->DialogChoose( idx );
				return;
			}
		}
	}

	if (VarName[0] != 0) {
		core->GetDictionary()->SetAt( VarName, Value );
	}
	RunEventHandler( TextAreaOnChange );
}
예제 #6
0
void Progressbar::UpdateState(unsigned int Sum)
{
	SetPosition(Sum);
	MarkDirty();
	if(Value==100)
		RunEventHandler( EndReached );
}
예제 #7
0
/** Sets a new position, relays the change to an associated textarea and calls
	any existing GUI OnChange callback */
void ScrollBar::SetPos(ieDword NewPos, bool redraw)
{
	if (!Frames[IE_GUI_SCROLLBAR_UP_UNPRESSED]) return;

	if (NewPos > Value) NewPos = Value;

	if (( State & SLIDER_GRAB ) == 0){
		// set the slider to the exact y for NewPos. in SetPosForY(y) it is set to any arbitrary position that may lie between 2 values.
		// if the slider is grabbed dont set position! otherwise you will get a flicker as it bounces between exact positioning and arbitrary
		SliderYPos = ( unsigned short ) ( GetFrameHeight(IE_GUI_SCROLLBAR_UP_UNPRESSED) +
			( NewPos * ( ( Height - GetFrameHeight(IE_GUI_SCROLLBAR_SLIDER) 
			- GetFrameHeight(IE_GUI_SCROLLBAR_UP_UNPRESSED)
			- GetFrameHeight(IE_GUI_SCROLLBAR_DOWN_UNPRESSED) ) /
			( double ) ( Value < 1 ? 1 : Value ) ) ) );
	}
	if (Pos && ( Pos == NewPos )) {
		return;
	}
	
	Changed = true;
	Pos = (ieWord) NewPos;
	if (ta) {
		(( TextArea* )ta)->SetRow( Pos );
	}
	if (VarName[0] != 0) {
		core->GetDictionary()->SetAt( VarName, Pos );
	}
	RunEventHandler( ScrollBarOnChange );
	if(redraw) core->RedrawAll();
}
예제 #8
0
파일: TextEdit.cpp 프로젝트: BehoIder/gemrb
/** Special Key Press */
bool TextEdit::OnSpecialKeyPress(unsigned char Key)
{
	int len;

	MarkDirty();
	switch (Key) {
		case GEM_HOME:
			CurPos = 0;
			break;
		case GEM_END:
			CurPos = (ieWord) strlen( (char * ) Buffer);
			break;
		case GEM_LEFT:
			if (CurPos > 0)
				CurPos--;
			break;
		case GEM_RIGHT:
			len = ( int ) strlen( ( char * ) Buffer );
			if (CurPos < len) {
				CurPos++;
			}
			break;
		case GEM_DELETE:
			len = ( int ) strlen( ( char * ) Buffer );
			if (CurPos < len) {
				for (int i = CurPos; i < len; i++) {
					Buffer[i] = Buffer[i + 1];
				}
			}
			break;		
		case GEM_BACKSP:
			if (CurPos != 0) {
				int len = ( int ) strlen( ( char* ) Buffer );
				for (int i = CurPos; i < len; i++) {
					Buffer[i - 1] = Buffer[i];
				}
				Buffer[len - 1] = 0;
				CurPos--;
			}
			break;
		case GEM_RETURN:
			RunEventHandler( EditOnDone );
	}
	RunEventHandler( EditOnChange );
	return true;
}
예제 #9
0
파일: Button.cpp 프로젝트: BehoIder/gemrb
/** Handling The default button (enter) */
bool Button::OnSpecialKeyPress(unsigned char Key)
{
	if (State != IE_GUI_BUTTON_DISABLED && State != IE_GUI_BUTTON_LOCKED) {
		if (Key == GEM_RETURN) {
			if (Flags & IE_GUI_BUTTON_DEFAULT ) {
				RunEventHandler( ButtonOnPress );
				return true;
			}
		}
		else if (Key == GEM_ESCAPE) {
			if (Flags & IE_GUI_BUTTON_CANCEL ) {
				RunEventHandler( ButtonOnPress );
				return true;
			}
		}
	}
	return Control::OnSpecialKeyPress(Key);
}
예제 #10
0
/** Mouse Button Down */
void Button::OnMouseDown(unsigned short x, unsigned short y,
	unsigned short Button, unsigned short Mod)
{
	if (State == IE_GUI_BUTTON_DISABLED) {
		Control::OnMouseDown(x,y,Button,Mod);
		return;
	}

	if (core->GetDraggedItem () && !ButtonOnDragDrop) {
		Control::OnMouseDown(x,y,Button,Mod);
		return;
	}

	ScrollBar* scrlbr = (ScrollBar*) sb;
	if (!scrlbr) {
		Control *ctrl = Owner->GetScrollControl();
		if (ctrl && (ctrl->ControlType == IE_GUI_SCROLLBAR)) {
			scrlbr = (ScrollBar *) ctrl;
		}
	}

	//Button == 1 means Left Mouse Button
	switch(Button&GEM_MB_NORMAL) {
	case GEM_MB_ACTION:
		// We use absolute screen position here, so drag_start
		//   remains valid even after window/control is moved
		drag_start.x = Owner->XPos + XPos + x;
		drag_start.y = Owner->YPos + YPos + y;

 		if (State == IE_GUI_BUTTON_LOCKED) {
			SetState( IE_GUI_BUTTON_LOCKED_PRESSED );
			return;
		}
		SetState( IE_GUI_BUTTON_PRESSED );
		if (Flags & IE_GUI_BUTTON_SOUND) {
			core->PlaySound( DS_BUTTON_PRESSED );
		}
		if ((Button & GEM_MB_DOUBLECLICK) && ButtonOnDoublePress) {
			RunEventHandler( ButtonOnDoublePress );
			printMessage("Button","Doubleclick detected\n",GREEN);
		}
		break;
	case GEM_MB_SCRLUP:
		if (scrlbr) {
			scrlbr->ScrollUp();
			core->RedrawAll();
		}
		break; 
	case GEM_MB_SCRLDOWN:
		if (scrlbr) {
			scrlbr->ScrollDown();
			core->RedrawAll();
		}
		break;
	}
}
예제 #11
0
파일: Button.cpp 프로젝트: BehoIder/gemrb
void Button::OnMouseLeave(unsigned short /*x*/, unsigned short /*y*/)
{
	if (State == IE_GUI_BUTTON_DISABLED) {
		return;
	}
	if (WantsDragOperation()) {
		core->GetDictionary()->SetAt( VarName, Value );
	}
	RunEventHandler( MouseLeaveButton );
}
예제 #12
0
void MapControl::ClickHandle(unsigned short Button)
{
	core->GetDictionary()->SetAt( "MapControlX", NotePosX );
	core->GetDictionary()->SetAt( "MapControlY", NotePosY );
	switch(Button&GEM_MB_NORMAL) {
		case GEM_MB_ACTION:
			if (Button&GEM_MB_DOUBLECLICK) {
				RunEventHandler( MapControlOnDoublePress );
			} else {
				RunEventHandler( MapControlOnPress );
			}
			break;
		case GEM_MB_MENU:
			RunEventHandler( MapControlOnRightPress );
			break;
		default:
			break;
	}
}
예제 #13
0
/** Mouse Button Up */
void WorldMapControl::OnMouseUp(unsigned short /*x*/, unsigned short /*y*/,
	unsigned short Button, unsigned short /*Mod*/)
{
	if (Button != GEM_MB_ACTION) {
		return;
	}
	MouseIsDown = false;
	if (lastCursor==IE_CURSOR_NORMAL) {
		RunEventHandler( WorldMapControlOnPress );
	}
}
예제 #14
0
파일: Button.cpp 프로젝트: BehoIder/gemrb
void Button::OnMouseEnter(unsigned short /*x*/, unsigned short /*y*/)
{
	if (State == IE_GUI_BUTTON_DISABLED) {
		return;
	}

	if (MouseEnterButton !=0 && VarName[0] != 0) {
		core->GetDictionary()->SetAt( VarName, Value );
	}

	RunEventHandler( MouseEnterButton );
}
예제 #15
0
void Label::OnMouseUp(unsigned short x, unsigned short y,
	unsigned short /*Button*/, unsigned short /*Mod*/)
{
	//printf( "Label::OnMouseUp\n" );
	if (( x <= Width ) && ( y <= Height )) {
		if (VarName[0] != 0) {
			core->GetDictionary()->SetAt( VarName, Value );
		}
		if (LabelOnPress) {
			RunEventHandler( LabelOnPress );
		}
	}
}
예제 #16
0
파일: Button.cpp 프로젝트: BehoIder/gemrb
void Button::OnMouseOver(unsigned short x, unsigned short y)
{
	Owner->Cursor = IE_CURSOR_NORMAL;
	if (State == IE_GUI_BUTTON_DISABLED) {
		return;
	}

	if ( RunEventHandler( MouseOverButton )<0) {
		//event handler destructed this object
		return;
	}

	//well, no more flags for buttons, and the portraits we can perform action on
	//are in fact 'draggable multiline pictures' (with image)
	if ((Flags & IE_GUI_BUTTON_DISABLED_P) == IE_GUI_BUTTON_PORTRAIT) {
		GameControl *gc = core->GetGameControl();
		if (gc) {
			Owner->Cursor = gc->GetDefaultCursor();
		}
	}

	if (State == IE_GUI_BUTTON_LOCKED) {
		return;
	}

	//portrait buttons are draggable and locked
	if ((Flags & IE_GUI_BUTTON_DRAGGABLE) && 
			      (State == IE_GUI_BUTTON_PRESSED || State ==IE_GUI_BUTTON_LOCKED_PRESSED)) {
		// We use absolute screen position here, so drag_start
		//   remains valid even after window/control is moved
		int dx = Owner->XPos + XPos + x - drag_start.x;
		int dy = Owner->YPos + YPos + y - drag_start.y;
		core->GetDictionary()->SetAt( "DragX", dx );
		core->GetDictionary()->SetAt( "DragY", dy );
		drag_start.x = (ieWord) (drag_start.x + dx);
		drag_start.y = (ieWord) (drag_start.y + dy);
		RunEventHandler( ButtonOnDrag );
	}
}
예제 #17
0
/** Key Press Event */
void TextArea::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
{
	if (Flags & IE_GUI_TEXTAREA_EDITABLE) {
		if (Key >= 0x20) {
			Owner->Invalidate();
			Changed = true;
			int len = GetRowLength(CurLine);
			//printf("len: %d Before: %s\n",len, lines[CurLine]);
			lines[CurLine] = (char *) realloc( lines[CurLine], len + 2 );
			for (int i = len; i > CurPos; i--) {
				lines[CurLine][i] = lines[CurLine][i - 1];
			}
			lines[CurLine][CurPos] = Key;
			lines[CurLine][len + 1] = 0;
			CurPos++;
			//printf("pos: %d After: %s\n",CurPos, lines[CurLine]);
			CalcRowCount();
			RunEventHandler( TextAreaOnChange );
		}
		return;
	}

	//Selectable=false for dialogs, rather unintuitive, but fact
	if ((Flags & IE_GUI_TEXTAREA_SELECTABLE) || ( Key < '1' ) || ( Key > '9' ))
		return;
	GameControl *gc = core->GetGameControl();
	if (gc && (gc->GetDialogueFlags()&DF_IN_DIALOG) ) {
		Changed = true;
		seltext=minrow-1;
		if ((unsigned int) seltext>=lines.size()) {
			return;
		}
		for(int i=0;i<Key-'0';i++) {
			do {
				seltext++;
				if ((unsigned int) seltext>=lines.size()) {
					return;
				}
			}
			while (strnicmp( lines[seltext], "[s=", 3 ) != 0 );
		}
		int idx=-1;
		sscanf( lines[seltext], "[s=%d,", &idx);
		if (idx==-1) {
			//this kills this object, don't use any more data!
			gc->EndDialog();
			return;
		}
		gc->DialogChoose( idx );
	}
}
예제 #18
0
파일: TextEdit.cpp 프로젝트: Esum/gemrb
/** Key Press Event */
bool TextEdit::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
{
	if (Key >= 0x20) {
		if (Value && ( (Key<'0') || (Key>'9') ) )
			return false;
		MarkDirty();
		if (Text.length() < max) {
			Text.insert(CurPos++, 1, Key);
		}
		RunEventHandler( EditOnChange );
		return true;
	}
	return false;
}
예제 #19
0
/** Sets a new position, relays the change to an associated textarea and calls
	any existing GUI OnChange callback */
void ScrollBar::SetPos(int NewPos)
{
	if (Pos && ( Pos == NewPos )) {
		return;
	}
	Changed = true;
	Pos = (ieWord) NewPos;
	if (ta) {
		TextArea* t = ( TextArea* ) ta;
		t->SetRow( Pos );
	}
	if (VarName[0] != 0) {
		core->GetDictionary()->SetAt( VarName, Pos );
	}
	RunEventHandler( ScrollBarOnChange );
}
예제 #20
0
파일: TextEdit.cpp 프로젝트: BehoIder/gemrb
/** Key Press Event */
bool TextEdit::OnKeyPress(unsigned char Key, unsigned short /*Mod*/)
{
	if (Key >= 0x20) {
		if (Value && ( (Key<'0') || (Key>'9') ) )
			return false;
		MarkDirty();
		int len = ( int ) strlen( ( char* ) Buffer );
		if (len + 1 < max) {
			for (int i = len; i > CurPos; i--) {
				Buffer[i] = Buffer[i - 1];
			}
			Buffer[CurPos] = Key;
			Buffer[len + 1] = 0;
			CurPos++;
		}
		RunEventHandler( EditOnChange );
		return true;
	}
	return false;
}
예제 #21
0
파일: Button.cpp 프로젝트: BehoIder/gemrb
/** Mouse Button Up */
void Button::OnMouseUp(unsigned short x, unsigned short y,
	unsigned short Button, unsigned short Mod)
{
	if (State == IE_GUI_BUTTON_DISABLED) {
		return;
	}

	//what was just dropped?
	int dragtype = 0;
	if (core->GetDraggedItem ()) dragtype=1;
	if (core->GetDraggedPortrait ()) dragtype=2;

	//if something was dropped, but it isn't handled here: it didn't happen
	if (dragtype && !ButtonOnDragDrop)
		return;

	switch (State) {
	case IE_GUI_BUTTON_PRESSED:
		if (ToggleState) {
			SetState( IE_GUI_BUTTON_SELECTED );
		} else {
			SetState( IE_GUI_BUTTON_UNPRESSED );
		}
		break;
	case IE_GUI_BUTTON_LOCKED_PRESSED:
		SetState( IE_GUI_BUTTON_LOCKED );
		break;
	}

	//in case of dragged/dropped portraits, allow the event to happen even
	//when we are out of bound
	if (dragtype!=2) {
		if (( x >= Width ) || ( y >= Height )) {
			return;
		}
	}
	if (Flags & IE_GUI_BUTTON_CHECKBOX) {
		//checkbox
		ToggleState = !ToggleState;
		if (ToggleState)
			SetState( IE_GUI_BUTTON_SELECTED );
		else
			SetState( IE_GUI_BUTTON_UNPRESSED );
		if (VarName[0] != 0) {
			ieDword tmp = 0;
			core->GetDictionary()->Lookup( VarName, tmp );
			tmp ^= Value;
			core->GetDictionary()->SetAt( VarName, tmp );
			Owner->RedrawControls( VarName, tmp );
		}
	} else {
		if (Flags & IE_GUI_BUTTON_RADIOBUTTON) {
			//radio button
			ToggleState = true;
			SetState( IE_GUI_BUTTON_SELECTED );
		}
		if (VarName[0] != 0) {
			core->GetDictionary()->SetAt( VarName, Value );
			Owner->RedrawControls( VarName, Value );
		}
	}

	switch (dragtype) {
		case 1:
			RunEventHandler( ButtonOnDragDrop );
			return;
		case 2:
			RunEventHandler( ButtonOnDragDropPortrait );
			return;
	}

	if ((Button&GEM_MB_NORMAL) == GEM_MB_ACTION) {
		if ((Mod & GEM_MOD_SHIFT) && ButtonOnShiftPress)
			RunEventHandler( ButtonOnShiftPress );
		else
			RunEventHandler( ButtonOnPress );
	} else {
		if (Button == GEM_MB_MENU && ButtonOnRightPress)
			RunEventHandler( ButtonOnRightPress );
	}
}
예제 #22
0
/** Special Key Press */
void TextArea::OnSpecialKeyPress(unsigned char Key)
{
	int len;
	int i;

	if (!(Flags&IE_GUI_TEXTAREA_EDITABLE)) {
		return;
	}
	Owner->Invalidate();
	Changed = true;
	switch (Key) {
		case GEM_HOME:
			CurPos = 0;
			CurLine = 0;
			break;
		case GEM_UP:
			if (CurLine) {
				CurLine--;
			}
			break;
		case GEM_DOWN:
			if (CurLine<lines.size()) {
				CurLine++;
			}
			break;
		case GEM_END:
			CurLine=lines.size()-1;
			CurPos = GetRowLength((unsigned int) CurLine);
			break;
		case GEM_LEFT:
			if (CurPos > 0) {
				CurPos--;
			} else {
				if (CurLine) {
					CurLine--;
					CurPos = GetRowLength(CurLine);
				}
			}
			break;
		case GEM_RIGHT:
			len = GetRowLength(CurLine);
			if (CurPos < len) {
				CurPos++;
			} else {
				if(CurLine<lines.size()) {
					CurPos=0;
					CurLine++;
				}
			}
			break;
		case GEM_DELETE:
			len = GetRowLength(CurLine);
			//printf("len: %d Before: %s\n",len, lines[CurLine]);
			if (CurPos>=len) {
				//TODO: merge next line
				break;
			}
			lines[CurLine] = (char *) realloc( lines[CurLine], len );
			for (i = CurPos; i < len; i++) {
				lines[CurLine][i] = lines[CurLine][i + 1];
			}
			//printf("pos: %d After: %s\n",CurPos, lines[CurLine]);
			break;
		case GEM_BACKSP:
			len = GetRowLength(CurLine);
			if (CurPos != 0) {
				//printf("len: %d Before: %s\n",len, lines[CurLine]);
				if (len<1) {
					break;
				}
				lines[CurLine] = (char *) realloc( lines[CurLine], len );
				for (i = CurPos; i < len; i++) {
					lines[CurLine][i - 1] = lines[CurLine][i];
				}
				lines[CurLine][len - 1] = 0;
				CurPos--;
				//printf("pos: %d After: %s\n",CurPos, lines[CurLine]);
			} else {
				if (CurLine) {
					//TODO: merge lines
					int oldline = CurLine;
					CurLine--;
					int old = GetRowLength(CurLine);
					//printf("len: %d Before: %s\n",old, lines[CurLine]);
					//printf("len: %d Before: %s\n",len, lines[oldline]);
					lines[CurLine] = (char *) realloc (lines[CurLine], len+old);
					memcpy(lines[CurLine]+old, lines[oldline],len);
					free(lines[oldline]);
					lines[CurLine][old+len]=0;
					lines.erase(lines.begin()+oldline);
					lrows.erase(lrows.begin()+oldline);
					CurPos = old;
					//printf("pos: %d len: %d After: %s\n",CurPos, GetRowLength(CurLine), lines[CurLine]);
				}
			}
			break;
		 case GEM_RETURN:
			//add an empty line after CurLine
			//printf("pos: %d Before: %s\n",CurPos, lines[CurLine]);
			lrows.insert(lrows.begin()+CurLine, 0);
			len = GetRowLength(CurLine);
			//copy the text after the cursor into the new line
			char *str = (char *) malloc(len-CurPos+2);
			memcpy(str, lines[CurLine]+CurPos, len-CurPos+1);
			str[len-CurPos+1] = 0;
			lines.insert(lines.begin()+CurLine+1, str);
			//truncate the current line
			lines[CurLine] = (char *) realloc (lines[CurLine], CurPos+1);
			lines[CurLine][CurPos]=0;
			//move cursor to next line beginning
			CurLine++;
			CurPos=0;
			//printf("len: %d After: %s\n",GetRowLength(CurLine-1), lines[CurLine-1]);
			//printf("len: %d After: %s\n",GetRowLength(CurLine), lines[CurLine]);
			break;
	}
	CalcRowCount();
	RunEventHandler( TextAreaOnChange );
}
예제 #23
0
void TextArea::Draw(unsigned short x, unsigned short y)
{
	/** Don't come back recursively */
	if (InternalFlags&TA_BITEMYTAIL) {
		return;
	}
	int tx=x+XPos;
	int ty=y+YPos;
	Region clip( tx, ty, Width, Height );
	Video *video = core->GetVideoDriver();

	if (Flags&IE_GUI_TEXTAREA_SPEAKER) {
		if (AnimPicture) {
			video->BlitSprite(AnimPicture, tx,ty, true, &clip);
			clip.x+=AnimPicture->Width;
			clip.w-=AnimPicture->Width;
		}
	}

	//this might look better in GlobalTimer
	//or you might want to change the animated button to work like this
	if (Flags &IE_GUI_TEXTAREA_SMOOTHSCROLL)
	{
		unsigned long thisTime;

		GetTime( thisTime);
		if (thisTime>starttime) {
			starttime = thisTime+ticks;
			smooth--;
			while (smooth<=0) {
				smooth+=ftext->maxHeight;
				if (startrow<rows) {
					startrow++;
				}
			}

			/** Forcing redraw of whole screen before drawing text*/
			Owner->Invalidate();
			InternalFlags |= TA_BITEMYTAIL;
			Owner->DrawWindow();
			InternalFlags &= ~TA_BITEMYTAIL;
		}
	}

	if (!Changed && !(Owner->Flags&WF_FLOAT) ) {
		return;
	}
	Changed = false;

	if (XPos == 65535) {
		return;
	}
	size_t linesize = lines.size();
	if (linesize == 0) {
		return;
	}

	//smooth vertical scrolling up
	if (Flags & IE_GUI_TEXTAREA_SMOOTHSCROLL) {
		clip.y+=smooth;
		clip.h-=smooth;
	}

	//if textarea is 'selectable' it actually means, it is a listbox
	//in this case the selected value equals the line number
	//if it is 'not selectable' it can still have selectable lines
	//but then it is like the dialog window in the main game screen:
	//the selected value is encoded into the line
	if (!(Flags & IE_GUI_TEXTAREA_SELECTABLE) ) {
		char* Buffer = (char *) malloc( 1 );
		Buffer[0] = 0;
		int len = 0;
		int lastlen = 0;
		for (size_t i = 0; i < linesize; i++) {
			if (strnicmp( "[s=", lines[i], 3 ) == 0) {
				int tlen;
				unsigned long idx, acolor, bcolor;
				char* rest;
				idx = strtoul( lines[i] + 3, &rest, 0 );
				if (*rest != ',')
					goto notmatched;
				acolor = strtoul( rest + 1, &rest, 16 );
				if (*rest != ',')
					goto notmatched;
				bcolor = strtoul( rest + 1, &rest, 16 );
				if (*rest != ']')
					goto notmatched;
				tlen = (int)(strstr( rest + 1, "[/s]" ) - rest - 1);
				if (tlen < 0)
					goto notmatched;
				len += tlen + 23;
				Buffer = (char *) realloc( Buffer, len + 2 );
				if (seltext == (int) i) {
					sprintf( Buffer + lastlen, "[color=%6.6lX]%.*s[/color]",
						acolor, tlen, rest + 1 );
				} else {
					sprintf( Buffer + lastlen, "[color=%6.6lX]%.*s[/color]",
						bcolor, tlen, rest + 1 );
				}
			} else {
				notmatched:
				len += ( int ) strlen( lines[i] ) + 1;
				Buffer = (char *) realloc( Buffer, len + 2 );
				memcpy( &Buffer[lastlen], lines[i], len - lastlen );
			}
			lastlen = len;
			if (i != linesize - 1) {
				Buffer[lastlen - 1] = '\n';
				Buffer[lastlen] = 0;
			}
		}
		video->SetClipRect( &clip );

		int pos;

		if (startrow==CurLine) {
			pos = CurPos;
		} else {
			pos = -1;
		}
		ftext->PrintFromLine( startrow, clip,
			( unsigned char * ) Buffer, palette,
			IE_FONT_ALIGN_LEFT, finit, Cursor, pos );
		free( Buffer );
		video->SetClipRect( NULL );
		//streaming text
		if (linesize>50) {
			//the buffer is filled enough
			return;
		}
		if (core->GetAudioDrv()->IsSpeaking() ) {
			//the narrator is still talking
			return;
		}
		if (RunEventHandler( TextAreaOutOfText )) {
			return;
		}
		if (linesize==lines.size()) {
			ResetEventHandler( TextAreaOutOfText );
			return;
		}
		AppendText("\n",-1);
		return;
	}
	// normal scrolling textarea
	int rc = 0;
	int sr = startrow;
	unsigned int i;
	int yl;
	for (i = 0; i < linesize; i++) {
		if (rc + lrows[i] <= sr) {
			rc += lrows[i];
			continue;
		}
		sr -= rc;
		Palette* pal = NULL;
		if (seltext == (int) i)
			pal = selected;
		else if (Value == i)
			pal = lineselpal;
		else
			pal = palette;
		ftext->PrintFromLine( sr, clip,
			( unsigned char * ) lines[i], pal,
			IE_FONT_ALIGN_LEFT, finit, NULL );
		yl = ftext->size[1].h*(lrows[i]-sr);
		clip.y+=yl;
		clip.h-=yl;
		break;
	}
	for (i++; i < linesize; i++) {
		Palette* pal = NULL;
		if (seltext == (int) i)
			pal = selected;
		else if (Value == i)
			pal = lineselpal;
		else
			pal = palette;
		ftext->Print( clip, ( unsigned char * ) lines[i], pal,
			IE_FONT_ALIGN_LEFT, true );
		yl = ftext->size[1].h*lrows[i];
		clip.y+=yl;
		clip.h-=yl;

	}
}
예제 #24
0
/** Mouse Button Down */
void Slider::OnMouseDown(unsigned short x, unsigned short y, unsigned short /*Button*/,
	unsigned short /*Mod*/)
{
	Changed = true;
	unsigned int oldPos = Pos;
	int mx = (KnobXPos + ( Pos * KnobStep ) - Knob->XPos);
	int my = (KnobYPos - Knob->YPos);
	int Mx = (mx + Knob->Width);
	int My = (my + Knob->Height);

	if (( x >= mx ) && ( y >= my )) {
		if (( x <= Mx ) && ( y <= My )) {
			State = IE_GUI_SLIDER_GRABBEDKNOB;
		} else {
			int mx = KnobXPos;
			int xmx = x - mx;
			if (x < mx) {
				SetPosition( 0 );
				if (oldPos != Pos) {
					RunEventHandler( SliderOnChange );
				}
				return;
			}
			int befst = xmx / KnobStep;
			if (befst >= KnobStepsCount) {
				SetPosition( KnobStepsCount - 1 );
				if (oldPos != Pos) {
					RunEventHandler( SliderOnChange );
				}
				return;
			}
			int aftst = befst + KnobStep;
			if (( xmx - ( befst * KnobStep ) ) <
				( ( aftst * KnobStep ) - xmx )) {
				SetPosition( befst );
			} else {
				SetPosition( aftst );
			}
			if (oldPos != Pos) {
				RunEventHandler( SliderOnChange );
			}
		}
	} else {
		int mx = KnobXPos;
		int xmx = x - mx;
		if (x < mx) {
			SetPosition( 0 );
			if (oldPos != Pos) {
				RunEventHandler( SliderOnChange );
			}
			return;
		}
		int befst = xmx / KnobStep;
		if (befst >= KnobStepsCount) {
			SetPosition( KnobStepsCount - 1 );
			if (oldPos != Pos) {
				RunEventHandler( SliderOnChange );
			}
			return;
		}
		int aftst = befst + KnobStep;
		if (( xmx - ( befst * KnobStep ) ) < ( ( aftst * KnobStep ) - xmx )) {
			SetPosition( befst );
		} else {
			SetPosition( aftst );
		}
		if (oldPos != Pos) {
			RunEventHandler( SliderOnChange );
		}
	}
}