30 ClassImp(TGRegionWithId);
34 TGRegionWithId *gCurrentRegion;
36 static TGRegion *gEmptyRegion = 0;
37 static Int_t gPointerX;
38 static Int_t gPointerY;
42 class TGRegionData : public TRefCnt {
44 friend class TGRegion;
51 TGRegionData() { fRgn = 0; fIsNull = kTRUE; AddReference(); }
53 TGRegionData &operator=(
const TGRegionData &r);
59 TGRegionData &TGRegionData::operator=(
const TGRegionData &r)
77 gEmptyRegion =
new TGRegion(kTRUE);
79 fData = gEmptyRegion->fData;
80 fData->AddReference();
86 TGRegion::TGRegion(Bool_t is_null)
88 fData =
new TGRegionData;
89 fData->fRgn = gVirtualX->CreateRegion();
90 fData->fIsNull = is_null;
96 TGRegion::TGRegion(Int_t x, Int_t y, UInt_t w, UInt_t h, ERegionType)
98 fData =
new TGRegionData;
99 fData->fRgn = gVirtualX->CreateRegion();
100 fData->fIsNull = kFALSE;
105 xr.fWidth = (UShort_t) w;
106 xr.fHeight = (UShort_t) h;
107 gVirtualX->UnionRectWithRegion(&xr, fData->fRgn, fData->fRgn);
113 TGRegion::TGRegion(Int_t n, TPoint *points, Bool_t winding)
115 fData =
new TGRegionData;
116 fData->fIsNull = kFALSE;
117 Point_t *gpoints =
new Point_t[n];
119 for (
int i = 0; i < n; i++) {
120 gpoints[i].fX = (Short_t) points[i].GetX();
121 gpoints[i].fY = (Short_t) points[i].GetY();
124 fData->fRgn = gVirtualX->PolygonRegion(gpoints, n, winding);
130 TGRegion::TGRegion(
const TArrayS &x,
const TArrayS &y, Bool_t winding)
132 fData =
new TGRegionData;
133 fData->fIsNull = kFALSE;
135 Int_t n = x.GetSize();
136 if (n != y.GetSize()) {
137 Error(
"TGRegion",
"x and y arrays must have same length");
140 Point_t *gpoints =
new Point_t[n];
142 for (
int i = 0; i < n; i++) {
143 gpoints[i].fX = x.GetArray()[i];
144 gpoints[i].fY = y.GetArray()[i];
147 fData->fRgn = gVirtualX->PolygonRegion(gpoints, n, winding);
153 TGRegion::TGRegion(Int_t n, Int_t *x, Int_t *y, Bool_t winding)
155 fData =
new TGRegionData;
156 fData->fIsNull = kFALSE;
157 Point_t *gpoints =
new Point_t[n];
159 for (
int i = 0; i < n; i++) {
160 gpoints[i].fX = x[i];
161 gpoints[i].fY = y[i];
164 fData->fRgn = gVirtualX->PolygonRegion(gpoints, n, winding);
170 TGRegion::TGRegion(
const TGRegion &r) : TObject(r)
173 fData->AddReference();
179 TGRegion::~TGRegion()
181 if (fData->RemoveReference() <= 0) {
182 gVirtualX->DestroyRegion(fData->fRgn);
190 TGRegion &TGRegion::operator=(
const TGRegion &r)
193 TObject::operator=(r);
194 r.fData->AddReference();
196 if (fData->RemoveReference() <= 0) {
197 gVirtualX->DestroyRegion(fData->fRgn);
208 TGRegion TGRegion::CopyRegion()
const
210 TGRegion r(fData->fIsNull);
211 gVirtualX->UnionRegion(fData->fRgn, r.fData->fRgn, r.fData->fRgn);
218 Bool_t TGRegion::IsNull()
const
220 return fData->fIsNull;
226 Bool_t TGRegion::IsEmpty()
const
228 return fData->fIsNull || gVirtualX->EmptyRegion(fData->fRgn);
234 Bool_t TGRegion::Contains(
const TPoint &p)
const
236 return gVirtualX->PointInRegion((Int_t)p.GetX(), (Int_t)p.GetY(), fData->fRgn);
242 Bool_t TGRegion::Contains(Int_t x, Int_t y)
const
244 return gVirtualX->PointInRegion(x, y, fData->fRgn);
250 TGRegion TGRegion::Unite(
const TGRegion &r)
const
252 TGRegion result(kFALSE);
253 gVirtualX->UnionRegion(fData->fRgn, r.fData->fRgn, result.fData->fRgn);
260 TGRegion TGRegion::Intersect(
const TGRegion &r)
const
262 TGRegion result(kFALSE);
263 gVirtualX->IntersectRegion(fData->fRgn, r.fData->fRgn, result.fData->fRgn);
270 TGRegion TGRegion::Subtract(
const TGRegion &r)
const
272 TGRegion result(kFALSE);
273 gVirtualX->SubtractRegion(fData->fRgn, r.fData->fRgn, result.fData->fRgn);
281 TGRegion TGRegion::Eor(
const TGRegion &r)
const
283 TGRegion result(kFALSE);
284 gVirtualX->XorRegion(fData->fRgn, r.fData->fRgn, result.fData->fRgn);
291 TGDimension TGRegion::GetDimension()
const
293 Rectangle_t r = { 0, 0, 0, 0 };
294 gVirtualX->GetRegionBox(fData->fRgn, &r);
295 return TGDimension(r.fWidth, r.fHeight);
301 TGPosition TGRegion::GetPosition()
const
303 Rectangle_t r = { 0, 0, 0, 0 };
304 gVirtualX->GetRegionBox(fData->fRgn, &r);
305 return TGPosition(r.fX, r.fY);
311 Bool_t TGRegion::operator==(
const TGRegion &r)
const
313 return fData == r.fData ?
314 kTRUE : gVirtualX->EqualRegion(fData->fRgn, r.fData->fRgn);
322 TGRegionWithId::TGRegionWithId() : TGRegion()
332 TGRegionWithId::TGRegionWithId(Int_t
id, Int_t x, Int_t y,
333 UInt_t w, UInt_t h, ERegionType type) :
334 TGRegion(x, y, w, h, type)
344 TGRegionWithId::TGRegionWithId(Int_t
id, Int_t n, TPoint *points,
346 TGRegion(n, points, winding)
356 TGRegionWithId::TGRegionWithId(
const TGRegionWithId ®) : TGRegion(reg)
366 TGRegionWithId::TGRegionWithId(
const TGRegion ®, Int_t
id) :
377 TGRegionWithId::~TGRegionWithId()
385 void TGRegionWithId::DisplayPopup()
387 if (fPopup) fPopup->PlaceMenu(gPointerX, gPointerY, kTRUE, kTRUE);
395 void TGRegionWithId::SetToolTipText(
const char *text, Long_t delayms,
396 const TGFrame *frame)
403 if (text && strlen(text))
404 fTip =
new TGToolTip(gClient->GetDefaultRoot(), frame, text, delayms);
411 TGImageMap::TGImageMap(
const TGWindow *p,
const TGPicture *pic) :
412 TGPictureButton(p, pic)
414 fCursorMouseOut = kPointer;
415 fCursorMouseOver = kHand;
416 fListOfRegions =
new TList;
420 fNavMode = kNavRegions;
422 SetDisabledPicture(fPic);
423 SetState(kButtonDisabled);
425 gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
426 kButtonPressMask | kButtonReleaseMask |
427 kPointerMotionMask, kNone, kNone);
429 AddInput(kKeyPressMask | kKeyReleaseMask | kPointerMotionMask |
430 kStructureNotifyMask | kLeaveWindowMask);
437 TGImageMap::TGImageMap(
const TGWindow *p,
const TString &pic) :
438 TGPictureButton(p, pic.Data())
440 fCursorMouseOut = kPointer;
441 fCursorMouseOver = kHand;
442 fListOfRegions =
new TList;
446 fNavMode = kNavRegions;
448 SetDisabledPicture(fPic);
449 SetState(kButtonDisabled);
451 gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
452 kButtonPressMask | kButtonReleaseMask |
453 kPointerMotionMask, kNone, kNone);
455 AddInput(kKeyPressMask | kKeyReleaseMask | kPointerMotionMask |
456 kStructureNotifyMask | kLeaveWindowMask);
463 TGImageMap::~TGImageMap()
468 fListOfRegions->Delete();
469 delete fListOfRegions;
475 void TGImageMap::AddRegion(
const TGRegion ®ion, Int_t
id)
477 fListOfRegions->Add(
new TGRegionWithId(region,
id));
483 TGPopupMenu *TGImageMap::CreatePopup(Int_t
id)
485 TIter next(fListOfRegions);
486 TGRegionWithId *region;
487 TGPopupMenu *popup = 0;
488 TGPopupMenu *newpopup = 0;
490 while ((region = (TGRegionWithId*)next())) {
491 if (
id == region->GetId()) {
492 popup = region->GetPopup();
493 if (!popup && !newpopup) {
494 newpopup =
new TGPopupMenu(
this);
495 fTrash->Add(newpopup);
497 if (newpopup) region->SetPopup(newpopup);
500 return newpopup ? newpopup : popup;
506 TGPopupMenu *TGImageMap::GetPopup(Int_t
id)
508 TIter next(fListOfRegions);
509 TGRegionWithId *region;
511 while ((region = (TGRegionWithId*)next())) {
512 if (
id == region->GetId())
return region->GetPopup();
520 Bool_t TGImageMap::HandleMotion(Event_t *event)
522 TIter next(fListOfRegions);
523 TGRegionWithId *region;
525 if (fNavMode != kNavRegions)
return kTRUE;
526 gPointerX =
event->fX;
527 gPointerY =
event->fY;
529 while ((region = (TGRegionWithId*)next())) {
530 if (region->Contains(gPointerX, gPointerY)) {
531 if (fLastVisited == region->GetId())
return kTRUE;
532 if (fLastVisited) OnMouseOut(fLastVisited);
533 fLastVisited = region->GetId();
534 fTip = region->GetToolTipText();
535 gCurrentRegion = region;
536 OnMouseOver(fLastVisited);
542 OnMouseOut(fLastVisited);
552 Bool_t TGImageMap::HandleDoubleClick(Event_t *event)
554 TIter next(fListOfRegions);
555 TGRegionWithId *region;
557 if (fTip) fTip->Hide();
558 if (event->fCode != kButton1 )
return kTRUE;
559 if (fNavMode != kNavRegions)
return kTRUE;
561 gPointerX =
event->fX;
562 gPointerY =
event->fY;
564 while ((region = (TGRegionWithId*)next())) {
565 if (region->Contains(gPointerX, gPointerY)) {
566 DoubleClicked(region->GetId());
567 gCurrentRegion = region;
578 Bool_t TGImageMap::HandleButton(Event_t *event)
580 TIter next(fListOfRegions);
581 TGRegionWithId *region;
584 if (fTip) fTip->Hide();
585 if (fNavMode != kNavRegions)
return kTRUE;
587 gPointerX =
event->fX;
588 gPointerY =
event->fY;
590 while ((region = (TGRegionWithId*)next())) {
591 if (region->Contains(gPointerX, gPointerY)) {
592 gCurrentRegion = region;
593 if (event->fType == kButtonPress) {
594 if (event->fCode == kButton1 )
595 RegionClicked(region->GetId());
596 else if (event->fCode == kButton3 ) {
597 pop = region->GetPopup();
598 if (pop) pop->PlaceMenu(gPointerX, gPointerY, kTRUE, kTRUE);
604 if (event->fType == kButtonPress)
612 void TGImageMap::SetToolTipText(
const char *text, Long_t delayms)
614 if (fMainTip)
delete fMainTip;
617 if (text && strlen(text))
618 fMainTip =
new TGToolTip(fClient->GetDefaultRoot(),
this, text, delayms);
624 void TGImageMap::SetToolTipText(Int_t
id,
const char *text, Long_t delayms)
626 TIter next(fListOfRegions);
627 TGRegionWithId *region;
629 while ((region = (TGRegionWithId*)next())) {
630 if (
id == region->GetId())
631 region->SetToolTipText(text, delayms,
this);
639 void TGImageMap::OnMouseOver(Int_t
id)
641 if (fTip) fTip->Reset();
642 if (fMainTip) fMainTip->Hide();
643 gVirtualX->SetCursor(fId, gVirtualX->CreateCursor(fCursorMouseOver));
644 Emit(
"OnMouseOver(Int_t)",
id);
651 void TGImageMap::OnMouseOut(Int_t
id)
653 if(fTip) fTip->Hide();
654 if(fMainTip) fMainTip->Reset();
655 gVirtualX->SetCursor(fId,gVirtualX->CreateCursor(fCursorMouseOut));
656 Emit(
"OnMouseOut(Int_t)",
id);
663 void TGImageMap::RegionClicked(Int_t
id)
665 Emit(
"RegionClicked(Int_t)",
id);
672 void TGImageMap::DoubleClicked()
674 Emit(
"DoubleClicked()");
681 void TGImageMap::DoubleClicked(Int_t
id)
683 Emit(
"DoubleClicked(Int_t)",
id);