00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 #include "TGResourcePool.h"
00042 #include "TGedPatternSelect.h"
00043 #include "TGToolTip.h"
00044 #include "TGButton.h"
00045 #include "Riostream.h"
00046 #include "RStipples.h"
00047 
00048 ClassImp(TGedPopup)
00049 ClassImp(TGedSelect)
00050 ClassImp(TGedPatternFrame)
00051 ClassImp(TGedPatternSelector)
00052 ClassImp(TGedPatternPopup)
00053 ClassImp(TGedPatternSelect)
00054 
00055 TGGC* TGedPatternFrame::fgGC = 0;
00056 
00057 
00058 
00059 TGedPatternFrame::TGedPatternFrame(const TGWindow *p, Style_t pattern,
00060                                    int width, int height)
00061    : TGFrame(p, width, height, kOwnBackground)
00062 {
00063    
00064 
00065    Pixel_t white;
00066    gClient->GetColorByName("white", white); 
00067    SetBackgroundColor(white);
00068 
00069    
00070    if (pattern == 1001)
00071       SetBackgroundColor(0);     
00072 
00073    fPattern = pattern;
00074 
00075    AddInput(kButtonPressMask | kButtonReleaseMask);
00076    fMsgWindow  = p;
00077    fActive = kFALSE;
00078    snprintf(fTipText, 5, "%d", pattern);
00079 
00080    
00081    if (pattern != 0 && pattern != 1001)
00082       fTip = new TGToolTip(fClient->GetDefaultRoot(), this, fTipText, 1000);
00083    else if (pattern == 0)
00084       fTip = new TGToolTip(fClient->GetDefaultRoot(), this, "0 - hollow", 1000);
00085    else 
00086       fTip = new TGToolTip(fClient->GetDefaultRoot(), this, "1001 - solid", 1000);
00087 
00088    AddInput(kEnterWindowMask | kLeaveWindowMask);
00089 
00090    if (!fgGC) {
00091       GCValues_t gcv;
00092       gcv.fMask = kGCLineStyle  | kGCLineWidth  | kGCFillStyle |
00093                   kGCForeground | kGCBackground;
00094       gcv.fLineStyle  = kLineSolid;
00095       gcv.fLineWidth  = 0;
00096       gcv.fFillStyle  = 0;
00097       gcv.fBackground = white;
00098       gcv.fForeground = 0;    
00099       fgGC = gClient->GetGC(&gcv, kTRUE);
00100    }
00101 }
00102 
00103 
00104 Bool_t TGedPatternFrame::HandleCrossing(Event_t *event)
00105 {
00106    
00107 
00108    if (fTip) {
00109       if (event->fType == kEnterNotify)
00110          fTip->Reset();
00111       else
00112          fTip->Hide();
00113    }
00114    return kTRUE;
00115 }
00116 
00117 
00118 Bool_t TGedPatternFrame::HandleButton(Event_t *event)
00119 {
00120    
00121 
00122    if (event->fType == kButtonPress) {
00123       SendMessage(fMsgWindow, MK_MSG(kC_PATTERNSEL, kPAT_CLICK), event->fCode, fPattern);
00124    } else {    
00125       SendMessage(fMsgWindow, MK_MSG(kC_PATTERNSEL, kPAT_SELCHANGED), event->fCode, fPattern);
00126    }
00127 
00128    return kTRUE;
00129 }
00130 
00131 
00132 void TGedPatternFrame::DrawBorder()
00133 {
00134    
00135 
00136    gVirtualX->DrawRectangle(fId, GetBckgndGC()(), 0, 0, fWidth, fHeight);
00137    Draw3dRectangle(kDoubleBorder | kSunkenFrame, 0, 0, fWidth, fHeight);
00138 }
00139 
00140 
00141 void TGedPatternFrame::DoRedraw()
00142 {
00143    
00144 
00145    TGFrame::DoRedraw();
00146 
00147    if (fPattern > 3000 && fPattern < 3026) {
00148       SetFillStyle(fgGC, fPattern);
00149       gVirtualX->FillRectangle(fId, fgGC->GetGC(), 0, 0, fWidth, fHeight);
00150    }
00151 }
00152 
00153 
00154 void TGedPatternFrame::SetFillStyle(TGGC* gc, Style_t fstyle)
00155 {
00156    
00157    
00158    
00159    
00160 
00161    Int_t style = fstyle/1000;
00162    Int_t fasi  = fstyle%1000;
00163    Int_t stn = (fasi >= 1 && fasi <=25) ? fasi : 2;
00164 
00165    static Pixmap_t fillPattern = 0;
00166 
00167    switch (style) {
00168       case 1:         
00169          gc->SetFillStyle(kFillSolid);
00170          break;
00171       case 2:         
00172          break;
00173       case 3:         
00174          gc->SetFillStyle(kFillStippled);
00175          if (fillPattern != 0) {
00176             gVirtualX->DeletePixmap(fillPattern);
00177             fillPattern = 0;
00178          }
00179          fillPattern = gVirtualX->CreateBitmap(gClient->GetDefaultRoot()->GetId(),
00180                                                (const char*)gStipples[stn], 16, 16);
00181          gc->SetStipple(fillPattern);
00182          break;
00183       default:
00184         break;
00185    }
00186 }
00187 
00188 
00189 TGedPatternSelector::TGedPatternSelector(const TGWindow *p) :
00190    TGCompositeFrame(p, 124, 190)
00191 {
00192    
00193 
00194    SetLayoutManager(new TGTileLayout(this, 1));
00195 
00196    Int_t i;
00197    for (i = 1; i <= 25; i++)
00198       fCe[i-1] = new TGedPatternFrame(this, 3000 + i);
00199 
00200    fCe[25] = new TGedPatternFrame(this, 0);
00201    fCe[26] = new TGedPatternFrame(this, 1001);
00202 
00203    for (i = 0; i < 27; i++)
00204       AddFrame(fCe[i], new TGLayoutHints(kLHintsNoHints));
00205 
00206    fMsgWindow  = p;
00207    fActive = -1;
00208 }
00209 
00210 
00211 TGedPatternSelector::~TGedPatternSelector()
00212 {
00213    
00214 
00215    Cleanup();
00216 }
00217 
00218 
00219 void TGedPatternSelector::SetActive(Int_t newat)
00220 {
00221    
00222 
00223    if (fActive != newat) {
00224       if ((fActive >= 0) && (fActive < 27)) {
00225          fCe[fActive]->SetActive(kFALSE);
00226       }
00227       fActive = newat;
00228       if ((fActive >= 0) && (fActive < 27)) {
00229          fCe[fActive]->SetActive(kTRUE);
00230       }
00231    }
00232 }
00233 
00234 
00235 Bool_t TGedPatternSelector::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
00236 {
00237    
00238 
00239    switch (GET_MSG(msg)) {
00240       case kC_PATTERNSEL:
00241          switch (GET_SUBMSG(msg)) {
00242             case kPAT_SELCHANGED:
00243                switch (parm1) {
00244                   case kButton1:
00245                      SendMessage(fMsgWindow, MK_MSG(kC_PATTERNSEL,
00246                                  kPAT_SELCHANGED), parm1, parm2);
00247                      break;
00248                }
00249                break;
00250             case kPAT_CLICK:
00251                switch (parm1) {
00252                   case kButton1:
00253                      SetActive(parm2);
00254                      break;
00255                }
00256                break;
00257          }
00258    }
00259 
00260    return kTRUE;
00261 }
00262 
00263 
00264 TGedPopup::TGedPopup(const TGWindow *p, const TGWindow *m, UInt_t w, UInt_t h,
00265                      UInt_t options, Pixel_t back)
00266    : TGCompositeFrame(p, w, h, options, back)
00267 {
00268    
00269 
00270    fMsgWindow = m;
00271    SetWindowAttributes_t wattr;
00272 
00273    wattr.fMask = kWAOverrideRedirect | kWASaveUnder ;
00274    wattr.fOverrideRedirect = kTRUE;
00275    wattr.fSaveUnder = kTRUE;
00276    gVirtualX->ChangeWindowAttributes(fId, &wattr);
00277 
00278    AddInput(kStructureNotifyMask);
00279 }
00280 
00281 
00282 void TGedPopup::EndPopup()
00283 {
00284    
00285 
00286    gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
00287    UnmapWindow();
00288 }
00289 
00290 
00291 void TGedPopup::PlacePopup(Int_t x, Int_t y, UInt_t w, UInt_t h)
00292 {
00293    
00294 
00295    Int_t rx, ry;
00296    UInt_t rw, rh;
00297 
00298    
00299    gVirtualX->GetWindowSize(fParent->GetId(), rx, ry, rw, rh);
00300 
00301    if (x < 0) x = 0;
00302    if (x + fWidth > rw) x = rw - fWidth;
00303    if (y < 0) y = 0;
00304    if (y + fHeight > rh) y = rh - fHeight;
00305 
00306    MoveResize(x, y, w, h);
00307    MapSubwindows();
00308    Layout();
00309    MapRaised();
00310 
00311    gVirtualX->GrabPointer(fId,
00312                           kButtonPressMask | kButtonReleaseMask | kPointerMotionMask,
00313                           kNone, kNone, fClient->GetResourcePool()->GetGrabCursor());
00314    gClient->WaitForUnmap(this);
00315    EndPopup();
00316 }
00317 
00318 
00319 Bool_t TGedPopup::HandleButton(Event_t *event)
00320 {
00321    
00322 
00323    if ((event->fX < 0) || (event->fX >= (Int_t) fWidth) ||
00324        (event->fY < 0) || (event->fY >= (Int_t) fHeight))  {
00325 
00326       if (event->fType == kButtonRelease) EndPopup();
00327 
00328    } else {
00329       TGFrame *f = GetFrameFromPoint(event->fX, event->fY);
00330       if (f && f != this) {
00331          TranslateCoordinates(f, event->fX, event->fY, event->fX, event->fY);
00332          f->HandleButton(event);
00333       }
00334    }
00335    return kTRUE;
00336 }
00337 
00338 
00339 Bool_t TGedPopup::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
00340 {
00341    
00342 
00343    switch (GET_MSG(msg)) {
00344       case kC_POPUP:
00345          switch (GET_SUBMSG(msg)) {
00346             case kPOP_HIDE:
00347                EndPopup();
00348                SendMessage(fMsgWindow, MK_MSG(kC_POPUP, kPOP_HIDE),
00349                            parm1, parm2);
00350                break;
00351             default:
00352                break;
00353          }
00354          break;
00355    }
00356    return kTRUE;
00357 }
00358 
00359 
00360 TGedPatternPopup::TGedPatternPopup(const TGWindow *p, const TGWindow *m, Style_t pattern)
00361    : TGedPopup(p, m, 10, 10, kDoubleBorder | kRaisedFrame | kOwnBackground,
00362                GetDefaultFrameBackground())
00363 {
00364    
00365 
00366    fCurrentPattern = pattern;
00367 
00368    TGedPatternSelector *ps = new TGedPatternSelector(this);
00369    AddFrame(ps, new TGLayoutHints(kLHintsCenterX, 1, 1, 1, 1));
00370 
00371    MapSubwindows();
00372    Resize(ps->GetDefaultWidth() + 6, ps->GetDefaultHeight());
00373 }
00374 
00375 
00376 TGedPatternPopup::~TGedPatternPopup()
00377 {
00378    
00379 
00380    Cleanup();
00381 }
00382 
00383 
00384 Bool_t TGedPatternPopup::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
00385 {
00386    
00387 
00388    switch (GET_MSG(msg)) {
00389       case kC_PATTERNSEL:
00390          switch (GET_SUBMSG(msg)) {
00391             case kPAT_SELCHANGED:
00392                SendMessage(fMsgWindow, MK_MSG(kC_PATTERNSEL, kPAT_SELCHANGED),
00393                            parm1, parm2);
00394                UnmapWindow();
00395                break;
00396 
00397             default:
00398                break;
00399          }
00400          break;
00401    }
00402    return kTRUE;
00403 }
00404 
00405 
00406 TGedSelect::TGedSelect(const TGWindow *p, Int_t id)
00407    : TGCheckButton(p, "", id)
00408 {
00409    
00410 
00411    fPopup = 0;
00412 
00413    GCValues_t gcv;
00414    gcv.fMask = kGCLineStyle  | kGCLineWidth  | kGCFillStyle |
00415                kGCForeground | kGCBackground;
00416    gcv.fLineStyle  = kLineSolid;
00417    gcv.fLineWidth  = 0;
00418    gcv.fFillStyle  = 0;
00419    Pixel_t white;
00420    gClient->GetColorByName("white", white); 
00421    gcv.fBackground = white;
00422    gcv.fForeground = 0;    
00423    fDrawGC = gClient->GetGC(&gcv, kTRUE);
00424 
00425    Enable();
00426    SetState(kButtonUp);
00427    AddInput(kButtonPressMask | kButtonReleaseMask);
00428 }
00429 
00430 
00431 TGedSelect::~TGedSelect()
00432 {
00433    
00434 
00435    if (fPopup)
00436       delete fPopup;
00437    fClient->FreeGC(fDrawGC);
00438 }
00439 
00440 
00441 Bool_t TGedSelect::HandleButton(Event_t *event)
00442 {
00443    
00444 
00445    TGFrame::HandleButton(event);
00446 
00447    if (!IsEnabled()) return kTRUE;
00448 
00449    if (event->fCode != kButton1) return kFALSE;
00450 
00451    if ((event->fType == kButtonPress) && HasFocus()) WantFocus();
00452 
00453    if (event->fType == kButtonPress) {
00454       if (fState != kButtonDown) {
00455          fPrevState = fState;
00456          SetState(kButtonDown);
00457       }
00458    } else {
00459       if (fState != kButtonUp) {
00460          SetState(kButtonUp);
00461          Window_t wdummy;
00462          Int_t ax, ay;
00463          if (fPopup) {
00464             gVirtualX->TranslateCoordinates(fId, gClient->GetDefaultRoot()->GetId(),
00465                                             0, fHeight, ax, ay, wdummy);
00466             fPopup->PlacePopup(ax, ay, fPopup->GetDefaultWidth(),
00467                                fPopup->GetDefaultHeight());
00468          }
00469       }
00470    }
00471    return kTRUE;
00472 }
00473 
00474 
00475 void TGedSelect::Enable()
00476 {
00477    
00478 
00479    SetFlags(kWidgetIsEnabled);
00480    fClient->NeedRedraw(this);
00481 }
00482 
00483 
00484 void TGedSelect::Disable()
00485 {
00486    
00487 
00488    ClearFlags(kWidgetIsEnabled);
00489    fClient->NeedRedraw(this);
00490 }
00491 
00492 
00493 void TGedSelect::DoRedraw()
00494 {
00495    
00496 
00497    Int_t  x, y;
00498    UInt_t h;
00499 
00500    TGButton::DoRedraw();
00501 
00502    if (IsEnabled()) {
00503 
00504       
00505       x = fWidth - 6 - fBorderWidth - 6;
00506       y = fBorderWidth + 1;
00507       h = fHeight - fBorderWidth - 1;  
00508 
00509       if (fState == kButtonDown) { ++x; ++y; }
00510 
00511       gVirtualX->DrawLine(fId, GetShadowGC()(),  x, y, x, h - 2);
00512       gVirtualX->DrawLine(fId, GetHilightGC()(), x + 1, y, x + 1, h - 1);
00513       gVirtualX->DrawLine(fId, GetHilightGC()(), x, h - 1, x + 1, h - 1);
00514 
00515       
00516 
00517       x = fWidth - 6 - fBorderWidth - 2;
00518       y = (fHeight - 4) / 2 + 1;
00519 
00520       if (fState == kButtonDown) { ++x; ++y; }
00521 
00522       DrawTriangle(GetShadowGC()(), x, y);
00523 
00524    } else {
00525 
00526       
00527       x = fWidth - 6 - fBorderWidth - 6;
00528       y = fBorderWidth + 1;
00529       h = fHeight - fBorderWidth - 1;  
00530 
00531       gVirtualX->DrawLine(fId, GetShadowGC()(),  x, y, x, h - 2);
00532       gVirtualX->DrawLine(fId, GetHilightGC()(), x + 1, y, x + 1, h - 1);
00533       gVirtualX->DrawLine(fId, GetHilightGC()(), x, h - 1, x + 1, h - 1);
00534 
00535       
00536 
00537       x = fWidth - 6 - fBorderWidth - 2;
00538       y = (fHeight - 4) / 2 + 1;
00539 
00540       DrawTriangle(GetHilightGC()(), x + 1, y + 1);
00541       DrawTriangle(GetShadowGC()(), x, y);
00542    }
00543 }
00544 
00545 
00546 void TGedSelect::DrawTriangle(GContext_t gc, Int_t x, Int_t y)
00547 {
00548    
00549 
00550    Point_t points[3];
00551 
00552    points[0].fX = x;
00553    points[0].fY = y;
00554    points[1].fX = x + 5;
00555    points[1].fY = y;
00556    points[2].fX = x + 2;
00557    points[2].fY = y + 3;
00558 
00559    gVirtualX->FillPolygon(fId, gc, points, 3);
00560 }
00561 
00562 
00563 
00564 TGedPatternSelect::TGedPatternSelect(const TGWindow *p, Style_t pattern, Int_t id)
00565    : TGedSelect(p, id)
00566 {
00567    
00568 
00569    fPattern = pattern;
00570    SetPopup(new TGedPatternPopup(gClient->GetDefaultRoot(), this, fPattern));
00571    SetPattern(fPattern);
00572 }
00573 
00574 
00575 Bool_t TGedPatternSelect::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
00576 {
00577    
00578 
00579    if (GET_MSG(msg) == kC_PATTERNSEL && GET_SUBMSG(msg) == kPAT_SELCHANGED)
00580    {
00581       SetPattern(parm2);
00582       parm1 = (Long_t)fWidgetId;
00583       SendMessage(fMsgWindow, MK_MSG(kC_PATTERNSEL, kPAT_SELCHANGED),
00584                   parm1, parm2);
00585    }
00586    return kTRUE;
00587 }
00588 
00589 
00590 void TGedPatternSelect::DoRedraw()
00591 {
00592    
00593 
00594    TGedSelect::DoRedraw();
00595 
00596    Int_t  x, y;
00597    UInt_t w, h;
00598 
00599    if (IsEnabled()) { 
00600 
00601       x = fBorderWidth + 2;
00602       y = fBorderWidth + 2;  
00603       h = fHeight - (fBorderWidth * 2) - 4;  
00604       w = h * 2;
00605       if (fState == kButtonDown) { ++x; ++y; }
00606 
00607       gVirtualX->DrawRectangle(fId, GetShadowGC()(), x, y, w - 1, h - 1);
00608 
00609       TGedPatternFrame::SetFillStyle(fDrawGC, 1001);
00610 
00611       Pixel_t white;
00612       gClient->GetColorByName("white", white); 
00613       fDrawGC->SetForeground(white);
00614       gVirtualX->FillRectangle(fId, fDrawGC->GetGC(), x + 1, y + 1, w - 2, h - 2);
00615 
00616       if (fPattern != 0) {
00617          fDrawGC->SetForeground(0);
00618          TGedPatternFrame::SetFillStyle(fDrawGC, fPattern);
00619          gVirtualX->FillRectangle(fId, fDrawGC->GetGC(), x + 1, y + 1, w - 2, h - 2);
00620       }
00621    } else { 
00622 
00623       x = fBorderWidth + 2;
00624       y = fBorderWidth + 2;  
00625       w = 42;
00626       h = fHeight - (fBorderWidth * 2) - 4;  
00627       Draw3dRectangle(kSunkenFrame, x, y, w, h);
00628    }
00629 }
00630 
00631 
00632 void TGedPatternSelect::SetPattern(Style_t pattern, Bool_t emit)
00633 {
00634    
00635 
00636    fPattern = pattern;
00637    gClient->NeedRedraw(this);
00638    if (emit)
00639       PatternSelected(fPattern);
00640 }
00641 
00642 
00643 void TGedPatternSelect::SavePrimitive(ostream &out, Option_t * )
00644 {
00645    
00646 
00647    out <<"   TGedPatternSelect *";
00648    out << GetName() << " = new TGedPatternSelect(" << fParent->GetName()
00649        << "," << fPattern << "," << WidgetId() << ");" << endl;
00650 }