Limit displayed TH1 y-axis to non-negatives on zoom

Hello,
I’m using win32gdk v3.10/1 on win2k.
I would like to limit the y-axis displayed on TH1 to be non-negative when the user zooms using the mouse (e.g. clip on zoom feature). To do this, I connected the following slot to TPad::RangeAxisChanged()

void myslot() { TIter next(gPad->GetListOfPrimitives()); TObject *obj; TAxis *paxis; while( obj = next()) { if (obj->InheritsFrom("TH1") && !obj->InheritsFrom("TH2")) { TH1 *ph = (TH1 *)obj; if (ph->GetMinimum()<0. && ph->GetMinimum()!=-1111.) { ph->SetMinimum(-1111.); gPad->Modified(); } break; } } }This almost works, but the user must click on the canvas to trigger the re-paint. If I replace the gPad->Modified() with gPad->Update(), I get a crash in THistPainter::Paint() - called from a different thread than my code (I don’t see my call in the traceback - shown below). Do you have any suggestions on how I might accomplish this “clip on zoom” feature? Thanks.

Ed Oltman
[ul]THistPainter::Paint(const char * 0x1036a564) line 1391 + 27 bytes
TH1::Paint(const char * 0x1036a564) line 3586
TPad::PaintModified() line 2772
TCanvas::Update() line 1682
TCanvas::HandleInput(EEventType kButton1Up, int 58, int 595) line 1043
TRootEmbeddedCanvas::HandleContainerButton(Event_t * 0x0012fc7c) line 145
TRootEmbeddedContainer::HandleButton(Event_t * 0x0012fc7c) line 45 + 22 bytes
TGFrame::HandleEvent(Event_t * 0x0012fc7c) line 388
TGClient::HandleEvent(Event_t * 0x0012fc7c) line 601
TGClient::ProcessOneEvent() line 459
TGClient::HandleInput() line 486 + 8 bytes
TGInputHandler::Notify() line 70
TWinNTSystem::DispatchOneEvent(unsigned char 0) line 778 + 23 bytes
TSystem::InnerLoop() line 304
TWinNTSystem::InnerLoop() line 857
TSystem::Run() line 272
TApplication::Run(unsigned char 0) line 769
TRint::Run(unsigned char 0) line 245
main(int 1, char * * 0x01536860) line 31
ROOT! mainCRTStartup + 227 bytes
[/ul]

Hi Ed,

I have added a protection in THistPainter::Paint when deleting class members in case this function is called recursively.
This may happen when executing a signal like “RangeAxisChanged”.
The fix is in CVS.

Rene

Hi Rene,
I can now call gPad->Update() from from code called by TPad::RangeAxisChaged(), but id does not cause the pad to refresh itself. Is there another way to cause a TH1 derived object to re-draw itself after SetMinumum(-1111) is called?m Thanks.

Ed

Ed,

Independently of the object type,
gPad->Modified();
gPad->Update();

should do the work

Rene

Rene,
I agree, the gPad->Modified() should work, and it does if I’m not in gui-land. Please have a look at the attached macro (which only seems to work right when its compiled w/ aclic (e.g. .L ctrls.c+, then ctrls())

This macro was generated from my application with the ctrl-s operation where I stripped away all but the bare essence, then added the code of interest to the slot UpdateSlider(), connected to gPad::RangeAxisChanged() - in addition to updating the horizontal slider, its supposed to clip the displayed y-axis to >0, but it does’nt quite work - the user must click on the canvas to make it happen.

Thanks…

Ed
ctrls.C (4.38 KB)