TVirtualX: clear old lines during DrawLine()

Hi,

I’m using gVirtualX->DrawLine() in my GUI to guide the eye to the center of a TBox when clicking or resizing it (fig. 1). During resize, however, the lines accumulate resulting in sort of a mess (fig. 2). I’ve played around with gVirtualX->Update() and gVirtualX->ClearWindow() without being able to remove obsolete lines properly, so that only the current center lines are displayed.

Any suggestions on how to accomplish that?

Cheers,
Greg

[code]void MyGui::ExecEvent(Int_t event, Int_t px, Int_t py, TObject *selected){

// if fBox is clicked or resized draw cross-hair in box center
if(selected == fBox){
	Double_t hPixCnv = (Double_t)(fCanvas->GetWh()-1);
	Double_t wPixCnv = (Double_t)(fCanvas->GetWw()-1);
	Int_t xHor1		= TMath::Nint( fBox->GetX1() * wPixCnv );
	Int_t xHor2		= TMath::Nint( fBox->GetX2() * wPixCnv );
	Int_t xVer		 = (xHor1 + xHor2) / 2;
	Int_t yVer1		= TMath::Nint( (1-fBox->GetY1()) * hPixCnv );
	Int_t yVer2		= TMath::Nint( (1-fBox->GetY2()) * hPixCnv );
	Int_t yHor		 = (yVer1 + yVer2) / 2;

	switch(event){
	case kButton1Down:
		gVirtualX->DrawLine(xVer,yVer1,xVer,yVer2);
		gVirtualX->DrawLine(xHor1,yHor,xHor2,yHor);

		// grabbed Left/Right/Top/Bottom ?
		if(TMath::Abs( gPad->AbsPixeltoX(px) - fBox->GetX1() ) < 0.01 )
			fL = true;
		else if(TMath::Abs( gPad->AbsPixeltoX(px) - fBox->GetX2() ) < 0.01 )
			fR = true;
		if(TMath::Abs( gPad->AbsPixeltoY(py) - fBox->GetY2() ) < 0.01 )
			fT = true;
		else if(TMath::Abs( gPad->AbsPixeltoY(py) - fBox->GetY1() ) < 0.01 )
			fB = true;
		break;

	case kButton1Motion:
		// recalculate lines
		if(fL) xHor1 = px;
		if(fR) xHor2 = px;
		xVer = (xHor1 + xHor2) / 2;
		if(fT) yVer2 = py;
		if(fB) yVer1 = py;
		yHor = (yVer1 + yVer2) / 2;
		gVirtualX->DrawLine(xVer,yVer1,xVer,yVer2);
		gVirtualX->DrawLine(xHor1,yHor,xHor2,yHor);
		break;

	case kButton1Up:
		fL = false;
		fR = false;
		fT = false;
		fB = false;
		break;

	default:	break;
	}
}

}[/code]




You should use the Xor mode to draw the line.

gVirtualX->SetDrawMode(TVirtualX::kInvert);  // set the drawing mode to XOR mode

and

gVirtualX->SetDrawMode(TVirtualX::kCopy); // set drawing mode back to normal (copy) mode

With xor mode a first line drawing will be visible, and a 2nd one exactly at the same place will erase it.

No success.
Attached is a minimal example that draws rose512.jpg and the TBox.
On my system (Linux 64bit), a box resize still draws multiple lines, no matter where in the ExecEvent function I place the DrawMode() commands.
MyGui.zip (2.83 KB)

[quote=“greg814”]No success.
Attached is a minimal example that draws rose512.jpg and the TBox.
On my system (Linux 64bit), a box resize still draws multiple lines, no matter where in the ExecEvent function I place the DrawMode() commands.[/quote]

I recommend to avoid using XOR operations. In general, it’s not a very good idea - there are platforms, where XOR is not available. Of course, if you use only X11/Win XOR will work.

Yes, Timur is right. As I told you:

So you should:

  1. Enter Xor mode

then loop on:
2) draw a line at position_1
3) before drawing line at position_2 redraw the line a postition_1 to erase it

  1. return to normal mode

Thanks, the redraw of the old line in 3) solved it!