00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "TGImageMap.h"
00022 #include "TRefCnt.h"
00023 #include "TGMenu.h"
00024 #include "TGToolTip.h"
00025 #include "TList.h"
00026 #include "TArrayS.h"
00027
00028
00029 ClassImp(TGRegion)
00030 ClassImp(TGRegionWithId)
00031 ClassImpQ(TGImageMap)
00032
00033
00034 TGRegionWithId *gCurrentRegion;
00035
00036 static TGRegion *gEmptyRegion = 0;
00037 static Int_t gPointerX;
00038 static Int_t gPointerY;
00039
00040
00041
00042 class TGRegionData : public TRefCnt {
00043
00044 friend class TGRegion;
00045
00046 private:
00047 Region_t fRgn;
00048 Bool_t fIsNull;
00049
00050 public:
00051 TGRegionData() { fRgn = 0; fIsNull = kTRUE; AddReference(); }
00052 ~TGRegionData() { }
00053 TGRegionData &operator=(const TGRegionData &r);
00054 };
00055
00056
00057 TGRegionData &TGRegionData::operator=(const TGRegionData &r)
00058 {
00059
00060
00061 fRefs = r.fRefs;
00062 fRgn = r.fRgn;
00063 fIsNull = r.fIsNull;
00064
00065 return *this;
00066 }
00067
00068
00069
00070
00071 TGRegion::TGRegion()
00072 {
00073
00074
00075 if (!gEmptyRegion)
00076 gEmptyRegion = new TGRegion(kTRUE);
00077
00078 fData = gEmptyRegion->fData;
00079 fData->AddReference();
00080 }
00081
00082
00083 TGRegion::TGRegion(Bool_t is_null)
00084 {
00085
00086
00087 fData = new TGRegionData;
00088 fData->fRgn = gVirtualX->CreateRegion();
00089 fData->fIsNull = is_null;
00090 }
00091
00092
00093 TGRegion::TGRegion(Int_t x, Int_t y, UInt_t w, UInt_t h, ERegionType)
00094 {
00095
00096
00097 fData = new TGRegionData;
00098 fData->fRgn = gVirtualX->CreateRegion();
00099 fData->fIsNull = kFALSE;
00100
00101 Rectangle_t xr;
00102 xr.fX = (Short_t) x;
00103 xr.fY = (Short_t) y;
00104 xr.fWidth = (UShort_t) w;
00105 xr.fHeight = (UShort_t) h;
00106 gVirtualX->UnionRectWithRegion(&xr, fData->fRgn, fData->fRgn);
00107 }
00108
00109
00110 TGRegion::TGRegion(Int_t n, TPoint *points, Bool_t winding)
00111 {
00112
00113
00114 fData = new TGRegionData;
00115 fData->fIsNull = kFALSE;
00116 Point_t *gpoints = new Point_t[n];
00117
00118 for (int i = 0; i < n; i++) {
00119 gpoints[i].fX = (Short_t) points[i].GetX();
00120 gpoints[i].fY = (Short_t) points[i].GetY();
00121 }
00122
00123 fData->fRgn = gVirtualX->PolygonRegion(gpoints, n, winding);
00124 }
00125
00126
00127 TGRegion::TGRegion(const TArrayS &x, const TArrayS &y, Bool_t winding)
00128 {
00129
00130
00131 fData = new TGRegionData;
00132 fData->fIsNull = kFALSE;
00133
00134 Int_t n = x.GetSize();
00135 if (n != y.GetSize()) {
00136 Error("TGRegion", "x and y arrays must have same length");
00137 return;
00138 }
00139 Point_t *gpoints = new Point_t[n];
00140
00141 for (int i = 0; i < n; i++) {
00142 gpoints[i].fX = x.GetArray()[i];
00143 gpoints[i].fY = y.GetArray()[i];
00144 }
00145
00146 fData->fRgn = gVirtualX->PolygonRegion(gpoints, n, winding);
00147 }
00148
00149
00150 TGRegion::TGRegion(Int_t n, Int_t *x, Int_t *y, Bool_t winding)
00151 {
00152
00153
00154 fData = new TGRegionData;
00155 fData->fIsNull = kFALSE;
00156 Point_t *gpoints = new Point_t[n];
00157
00158 for (int i = 0; i < n; i++) {
00159 gpoints[i].fX = x[i];
00160 gpoints[i].fY = y[i];
00161 }
00162
00163 fData->fRgn = gVirtualX->PolygonRegion(gpoints, n, winding);
00164 }
00165
00166
00167 TGRegion::TGRegion(const TGRegion &r) : TObject(r)
00168 {
00169
00170
00171 fData = r.fData;
00172 fData->AddReference();
00173 }
00174
00175
00176 TGRegion::~TGRegion()
00177 {
00178
00179
00180 if (fData->RemoveReference() <= 0) {
00181 gVirtualX->DestroyRegion(fData->fRgn);
00182 delete fData;
00183 }
00184 }
00185
00186
00187 TGRegion &TGRegion::operator=(const TGRegion &r)
00188 {
00189
00190
00191 if (this != &r) {
00192 r.fData->AddReference();
00193
00194 if (fData->RemoveReference() <= 0) {
00195 gVirtualX->DestroyRegion(fData->fRgn);
00196 delete fData;
00197 }
00198 fData = r.fData;
00199 }
00200 return *this;
00201 }
00202
00203
00204 TGRegion TGRegion::CopyRegion() const
00205 {
00206
00207
00208 TGRegion r(fData->fIsNull);
00209 gVirtualX->UnionRegion(fData->fRgn, r.fData->fRgn, r.fData->fRgn);
00210 return r;
00211 }
00212
00213
00214 Bool_t TGRegion::IsNull() const
00215 {
00216
00217
00218 return fData->fIsNull;
00219 }
00220
00221
00222 Bool_t TGRegion::IsEmpty() const
00223 {
00224
00225
00226 return fData->fIsNull || gVirtualX->EmptyRegion(fData->fRgn);
00227 }
00228
00229
00230 Bool_t TGRegion::Contains(const TPoint &p) const
00231 {
00232
00233
00234 return gVirtualX->PointInRegion((Int_t)p.GetX(), (Int_t)p.GetY(), fData->fRgn);
00235 }
00236
00237
00238 Bool_t TGRegion::Contains(Int_t x, Int_t y) const
00239 {
00240
00241
00242 return gVirtualX->PointInRegion(x, y, fData->fRgn);
00243 }
00244
00245
00246 TGRegion TGRegion::Unite(const TGRegion &r) const
00247 {
00248
00249
00250 TGRegion result(kFALSE);
00251 gVirtualX->UnionRegion(fData->fRgn, r.fData->fRgn, result.fData->fRgn);
00252 return result;
00253 }
00254
00255
00256 TGRegion TGRegion::Intersect(const TGRegion &r) const
00257 {
00258
00259
00260 TGRegion result(kFALSE);
00261 gVirtualX->IntersectRegion(fData->fRgn, r.fData->fRgn, result.fData->fRgn);
00262 return result;
00263 }
00264
00265
00266 TGRegion TGRegion::Subtract(const TGRegion &r) const
00267 {
00268
00269
00270 TGRegion result(kFALSE);
00271 gVirtualX->SubtractRegion(fData->fRgn, r.fData->fRgn, result.fData->fRgn);
00272 return result;
00273 }
00274
00275
00276 TGRegion TGRegion::Eor(const TGRegion &r) const
00277 {
00278
00279
00280
00281 TGRegion result(kFALSE);
00282 gVirtualX->XorRegion(fData->fRgn, r.fData->fRgn, result.fData->fRgn);
00283 return result;
00284 }
00285
00286
00287 TGDimension TGRegion::GetDimension() const
00288 {
00289
00290
00291 Rectangle_t r = { 0, 0, 0, 0 };
00292 gVirtualX->GetRegionBox(fData->fRgn, &r);
00293 return TGDimension(r.fWidth, r.fHeight);
00294 }
00295
00296
00297 TGPosition TGRegion::GetPosition() const
00298 {
00299
00300
00301 Rectangle_t r = { 0, 0, 0, 0 };
00302 gVirtualX->GetRegionBox(fData->fRgn, &r);
00303 return TGPosition(r.fX, r.fY);
00304 }
00305
00306
00307 Bool_t TGRegion::operator==(const TGRegion &r) const
00308 {
00309
00310
00311 return fData == r.fData ?
00312 kTRUE : gVirtualX->EqualRegion(fData->fRgn, r.fData->fRgn);
00313 }
00314
00315
00316
00317
00318 TGRegionWithId::TGRegionWithId() : TGRegion()
00319 {
00320
00321
00322 fId = 0;
00323 fTip = 0;
00324 fPopup = 0;
00325 }
00326
00327
00328 TGRegionWithId::TGRegionWithId(Int_t id, Int_t x, Int_t y,
00329 UInt_t w, UInt_t h, ERegionType type) :
00330 TGRegion(x, y, w, h, type)
00331 {
00332
00333
00334 fId = id;
00335 fTip = 0;
00336 fPopup = 0;
00337 }
00338
00339
00340 TGRegionWithId::TGRegionWithId(Int_t id, Int_t n, TPoint *points,
00341 Bool_t winding) :
00342 TGRegion(n, points, winding)
00343 {
00344
00345
00346 fId = id;
00347 fTip = 0;
00348 fPopup = 0;
00349 }
00350
00351
00352 TGRegionWithId::TGRegionWithId(const TGRegionWithId ®) : TGRegion(reg)
00353 {
00354
00355
00356 fId = reg.GetId();
00357 fTip = 0;
00358 fPopup = 0;
00359 }
00360
00361
00362 TGRegionWithId::TGRegionWithId(const TGRegion ®, Int_t id) :
00363 TGRegion(reg)
00364 {
00365
00366
00367 fId = id;
00368 fTip = 0;
00369 fPopup = 0;
00370 }
00371
00372
00373 TGRegionWithId::~TGRegionWithId()
00374 {
00375
00376
00377 delete fTip;
00378 }
00379
00380
00381 void TGRegionWithId::DisplayPopup()
00382 {
00383
00384
00385 if (fPopup) fPopup->PlaceMenu(gPointerX, gPointerY, kFALSE, kTRUE);
00386 }
00387
00388
00389 void TGRegionWithId::SetToolTipText(const char *text, Long_t delayms,
00390 const TGFrame *frame)
00391 {
00392
00393
00394
00395
00396 if (fTip) {
00397 delete fTip;
00398 fTip = 0;
00399 }
00400
00401 if (text && strlen(text))
00402 fTip = new TGToolTip(gClient->GetDefaultRoot(), frame, text, delayms);
00403 }
00404
00405
00406
00407 TGImageMap::TGImageMap(const TGWindow *p, const TGPicture *pic) :
00408 TGPictureButton(p, pic)
00409 {
00410
00411
00412 fCursorMouseOut = kPointer;
00413 fCursorMouseOver = kHand;
00414 fListOfRegions = new TList;
00415 fTrash = new TList;
00416 fMainTip = 0;
00417 fNavMode = kNavRegions;
00418
00419 SetDisabledPicture(fPic);
00420 SetState(kButtonDisabled);
00421
00422 gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
00423 kButtonPressMask | kButtonReleaseMask |
00424 kPointerMotionMask, kNone, kNone);
00425
00426 AddInput(kKeyPressMask | kKeyReleaseMask | kPointerMotionMask |
00427 kStructureNotifyMask | kLeaveWindowMask);
00428 SetWindowName();
00429 }
00430
00431
00432 TGImageMap::TGImageMap(const TGWindow *p, const TString &pic) :
00433 TGPictureButton(p, pic.Data())
00434 {
00435
00436
00437 fCursorMouseOut = kPointer;
00438 fCursorMouseOver = kHand;
00439 fListOfRegions = new TList;
00440 fTrash = new TList;
00441 fMainTip = 0;
00442 fNavMode = kNavRegions;
00443
00444 SetDisabledPicture(fPic);
00445 SetState(kButtonDisabled);
00446
00447 gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
00448 kButtonPressMask | kButtonReleaseMask |
00449 kPointerMotionMask, kNone, kNone);
00450
00451 AddInput(kKeyPressMask | kKeyReleaseMask | kPointerMotionMask |
00452 kStructureNotifyMask | kLeaveWindowMask);
00453 SetWindowName();
00454 }
00455
00456
00457 TGImageMap::~TGImageMap()
00458 {
00459
00460
00461 delete fMainTip;
00462 fTrash->Delete();
00463 delete fTrash;
00464 fListOfRegions->Delete();
00465 delete fListOfRegions;
00466 }
00467
00468
00469 void TGImageMap::AddRegion(const TGRegion ®ion, Int_t id)
00470 {
00471
00472
00473 fListOfRegions->Add(new TGRegionWithId(region, id));
00474 }
00475
00476
00477 TGPopupMenu *TGImageMap::CreatePopup(Int_t id)
00478 {
00479
00480
00481 TIter next(fListOfRegions);
00482 TGRegionWithId *region;
00483 TGPopupMenu *popup = 0;
00484 TGPopupMenu *newpopup = 0;
00485
00486 while ((region = (TGRegionWithId*)next())) {
00487 if (id == region->GetId()) {
00488 popup = region->GetPopup();
00489 if (!popup && !newpopup) {
00490 newpopup = new TGPopupMenu(this);
00491 fTrash->Add(newpopup);
00492 }
00493 if (newpopup) region->SetPopup(newpopup);
00494 }
00495 }
00496 return newpopup ? newpopup : popup;
00497 }
00498
00499
00500 TGPopupMenu *TGImageMap::GetPopup(Int_t id)
00501 {
00502
00503
00504 TIter next(fListOfRegions);
00505 TGRegionWithId *region;
00506
00507 while ((region = (TGRegionWithId*)next())) {
00508 if (id == region->GetId()) return region->GetPopup();
00509 }
00510 return 0;
00511 }
00512
00513
00514 Bool_t TGImageMap::HandleMotion(Event_t *event)
00515 {
00516
00517
00518 TIter next(fListOfRegions);
00519 TGRegionWithId *region;
00520
00521 if (fNavMode != kNavRegions) return kTRUE;
00522 gPointerX = event->fX;
00523 gPointerY = event->fY;
00524
00525 while ((region = (TGRegionWithId*)next())) {
00526 if (region->Contains(gPointerX, gPointerY)) {
00527 if (fLastVisited == region->GetId()) return kTRUE;
00528 if (fLastVisited) OnMouseOut(fLastVisited);
00529 fLastVisited = region->GetId();
00530 fTip = region->GetToolTipText();
00531 gCurrentRegion = region;
00532 OnMouseOver(fLastVisited);
00533 return kTRUE;
00534 }
00535 }
00536
00537 if (fLastVisited) {
00538 OnMouseOut(fLastVisited);
00539 fTip = fMainTip;
00540 }
00541 fLastVisited = 0;
00542 return kTRUE;
00543 }
00544
00545
00546 Bool_t TGImageMap::HandleDoubleClick(Event_t *event)
00547 {
00548
00549
00550 TIter next(fListOfRegions);
00551 TGRegionWithId *region;
00552
00553 if (fTip) fTip->Hide();
00554 if (event->fCode != kButton1 ) return kTRUE;
00555 if (fNavMode != kNavRegions) return kTRUE;
00556
00557 gPointerX = event->fX;
00558 gPointerY = event->fY;
00559
00560 while ((region = (TGRegionWithId*)next())) {
00561 if (region->Contains(gPointerX, gPointerY)) {
00562 DoubleClicked(region->GetId());
00563 gCurrentRegion = region;
00564 return kTRUE;
00565 }
00566 }
00567 DoubleClicked();
00568 return kTRUE;
00569 }
00570
00571
00572 Bool_t TGImageMap::HandleButton(Event_t *event)
00573 {
00574
00575
00576 TIter next(fListOfRegions);
00577 TGRegionWithId *region;
00578 TGPopupMenu *pop;
00579
00580 if (fTip) fTip->Hide();
00581 if (fNavMode != kNavRegions) return kTRUE;
00582
00583 gPointerX = event->fX;
00584 gPointerY = event->fY;
00585
00586 while ((region = (TGRegionWithId*)next())) {
00587 if (region->Contains(gPointerX, gPointerY)) {
00588 gCurrentRegion = region;
00589 if (event->fType == kButtonPress) {
00590 if (event->fCode == kButton1 )
00591 RegionClicked(region->GetId());
00592 else if (event->fCode == kButton3 ) {
00593 pop = region->GetPopup();
00594 if (pop) pop->PlaceMenu(gPointerX, gPointerY, kFALSE, kTRUE);
00595 }
00596 }
00597 return kTRUE;
00598 }
00599 }
00600 if (event->fType == kButtonPress)
00601 Clicked();
00602 return kTRUE;
00603 }
00604
00605
00606 void TGImageMap::SetToolTipText(const char *text, Long_t delayms)
00607 {
00608
00609
00610 if (fMainTip) delete fMainTip;
00611 fMainTip = 0;
00612
00613 if (text && strlen(text))
00614 fMainTip = new TGToolTip(fClient->GetDefaultRoot(), this, text, delayms);
00615 }
00616
00617
00618 void TGImageMap::SetToolTipText(Int_t id, const char *text, Long_t delayms)
00619 {
00620
00621
00622 TIter next(fListOfRegions);
00623 TGRegionWithId *region;
00624
00625 while ((region = (TGRegionWithId*)next())) {
00626 if (id == region->GetId())
00627 region->SetToolTipText(text, delayms, this);
00628 }
00629 }
00630
00631
00632 void TGImageMap::OnMouseOver(Int_t id)
00633 {
00634
00635
00636
00637 if (fTip) fTip->Reset();
00638 if (fMainTip) fMainTip->Hide();
00639 gVirtualX->SetCursor(fId, gVirtualX->CreateCursor(fCursorMouseOver));
00640 Emit("OnMouseOver(Int_t)", id);
00641 }
00642
00643
00644 void TGImageMap::OnMouseOut(Int_t id)
00645 {
00646
00647
00648
00649 if(fTip) fTip->Hide();
00650 if(fMainTip) fMainTip->Reset();
00651 gVirtualX->SetCursor(fId,gVirtualX->CreateCursor(fCursorMouseOut));
00652 Emit("OnMouseOut(Int_t)",id);
00653 }
00654
00655
00656 void TGImageMap::RegionClicked(Int_t id)
00657 {
00658
00659
00660
00661 Emit("RegionClicked(Int_t)",id);
00662 }
00663
00664
00665 void TGImageMap::DoubleClicked()
00666 {
00667
00668
00669
00670 Emit("DoubleClicked()");
00671 }
00672
00673
00674 void TGImageMap::DoubleClicked(Int_t id)
00675 {
00676
00677
00678
00679 Emit("DoubleClicked(Int_t)",id);
00680 }