TGView.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TGView.cxx 31685 2009-12-08 16:33:13Z bellenot $
00002 // Author: Fons Rademakers   30/6/2000
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 /**************************************************************************
00012 
00013     This source is based on Xclass95, a Win95-looking GUI toolkit.
00014     Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
00015 
00016     Xclass95 is free software; you can redistribute it and/or
00017     modify it under the terms of the GNU Library General Public
00018     License as published by the Free Software Foundation; either
00019     version 2 of the License, or (at your option) any later version.
00020 
00021 **************************************************************************/
00022 
00023 //////////////////////////////////////////////////////////////////////////
00024 //                                                                      //
00025 // TGView                                                               //
00026 //                                                                      //
00027 // A TGView provides the infrastructure for text viewer and editor      //
00028 // widgets. It provides a canvas (TGViewFrame) and (optionally) a       //
00029 // vertical and horizontal scrollbar and methods for marking and        //
00030 // scrolling.                                                           //
00031 //                                                                      //
00032 // The TGView (and derivatives) will generate the following             //
00033 // event messages:                                                      //
00034 // kC_TEXTVIEW, kTXT_ISMARKED, widget id, [true|false]                  //
00035 // kC_TEXTVIEW, kTXT_DATACHANGE, widget id, 0                           //
00036 // kC_TEXTVIEW, kTXT_CLICK2, widget id, position (y << 16) | x)         //
00037 // kC_TEXTVIEW, kTXT_CLICK3, widget id, position (y << 16) | x)         //
00038 // kC_TEXTVIEW, kTXT_F3, widget id, true                                //
00039 // kC_TEXTVIEW, kTXT_OPEN, widget id, 0                                 //
00040 // kC_TEXTVIEW, kTXT_CLOSE, widget id, 0                                //
00041 // kC_TEXTVIEW, kTXT_SAVE, widget id, 0                                 //
00042 //                                                                      //
00043 //////////////////////////////////////////////////////////////////////////
00044 
00045 #include "TGView.h"
00046 #include "TGScrollBar.h"
00047 #include "TGResourcePool.h"
00048 #include "TMath.h"
00049 #include "KeySymbols.h"
00050 
00051 
00052 
00053 ClassImp(TGViewFrame)
00054 
00055 //______________________________________________________________________________
00056 TGViewFrame::TGViewFrame(TGView *v, UInt_t w, UInt_t h, UInt_t options,
00057                          ULong_t back) :
00058    TGCompositeFrame(v, w, h, options | kOwnBackground, back)
00059 {
00060    // Create a editor frame.
00061 
00062    fView = v;
00063 
00064    SetBackgroundColor(back);
00065       
00066    gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
00067                          kButtonPressMask | kButtonReleaseMask |
00068                          kButtonMotionMask, kNone, kNone);
00069 
00070    AddInput(kKeyPressMask | kEnterWindowMask | kLeaveWindowMask |
00071             kFocusChangeMask);
00072 
00073    SetWindowAttributes_t wattr;
00074    wattr.fMask = kWAWinGravity | kWABitGravity;
00075    wattr.fBitGravity = 1; // NorthWestGravity
00076    wattr.fWinGravity = 1;
00077    gVirtualX->ChangeWindowAttributes(fId, &wattr);
00078 
00079    // guibuiding settings
00080    fEditDisabled = kEditDisableGrab | kEditDisableKeyEnable | kEditDisableBtnEnable;
00081 }
00082 
00083 
00084 ClassImp(TGView)
00085 
00086 //______________________________________________________________________________
00087 TGView::TGView(const TGWindow *p, UInt_t w, UInt_t h, Int_t id,
00088                UInt_t xMargin, UInt_t yMargin, UInt_t options,
00089                UInt_t sboptions, ULong_t back)
00090        : TGCompositeFrame(p, w, h, options, GetDefaultFrameBackground())
00091 {
00092    // Create an editor view, containing an TGEditorFrame and (optionally)
00093    // a horizontal and vertical scrollbar.
00094 
00095    fWidgetId    = id;
00096    fMsgWindow   = p;
00097    fWidgetFlags = kWidgetWantFocus;
00098 
00099    fXMargin = xMargin;
00100    fYMargin = yMargin;
00101    fScrollVal.fX = 1;
00102    fScrollVal.fY = 1;
00103    fExposedRegion.Empty();
00104 
00105    fClipboard = fClient->GetResourcePool()->GetClipboard();
00106 
00107    fCanvas = new TGViewFrame(this, 10, 10, kChildFrame | kOwnBackground, back);
00108    AddFrame(fCanvas);
00109 
00110    if (!(sboptions & kNoHSB)) {
00111       fHsb = new TGHScrollBar(this, 10, 10, kChildFrame);
00112       AddFrame(fHsb);
00113       fHsb->Associate(this);
00114    } else {
00115       fHsb = 0;
00116    }
00117 
00118    if (!(sboptions & kNoVSB)) {
00119       fVsb = new TGVScrollBar(this, 10, 10, kChildFrame);
00120       AddFrame(fVsb);
00121       fVsb->Associate(this);
00122    } else {
00123       fVsb = 0;
00124    }
00125 
00126    fWhiteGC.SetGraphicsExposures(kTRUE);
00127    fWhiteGC.SetBackground(back);
00128 
00129    // sets for guibuilding   
00130    if (fVsb) {
00131       fVsb->SetEditDisabled(kEditDisableGrab | kEditDisableBtnEnable);
00132    }
00133    if (fHsb) {
00134       fHsb->SetEditDisabled(kEditDisableGrab  | kEditDisableBtnEnable);
00135    }
00136 
00137    fEditDisabled = kEditDisableLayout;
00138 
00139    // layout manager is not used
00140    delete fLayoutManager;
00141    fLayoutManager = 0;
00142 }
00143 
00144 //______________________________________________________________________________
00145 TGView::~TGView()
00146 {
00147    // Delete view.
00148 
00149    if (!MustCleanup()) {
00150       delete fCanvas;
00151       delete fHsb;
00152       delete fVsb;
00153    }
00154 }
00155 
00156 //______________________________________________________________________________
00157 void TGView::Clear(Option_t *)
00158 {
00159    // Clear view.
00160 
00161    fScrolling = -1;
00162 
00163    fMousePos.fX = fMousePos.fY = -1;
00164    fVisible.fX  = fVisible.fY = 0;
00165    UpdateBackgroundStart();
00166    fVirtualSize = TGDimension(0, 0);
00167 
00168    gVirtualX->ClearArea(fCanvas->GetId(), 0, 0,
00169                         fCanvas->GetWidth(), fCanvas->GetHeight());
00170    Layout();
00171 }
00172 
00173 //______________________________________________________________________________
00174 void TGView::SetVisibleStart(Int_t newTop, Int_t direction)
00175 {
00176    // Scroll view in specified direction to make newTop the visible location.
00177 
00178    if (direction == kHorizontal) {
00179       if (newTop / fScrollVal.fX == fVisible.fX / fScrollVal.fX) {
00180          return;
00181       }
00182       ScrollCanvas(newTop, kHorizontal);
00183    } else {
00184       if (newTop / fScrollVal.fY == fVisible.fY / fScrollVal.fY) {
00185          return;
00186       }
00187       ScrollCanvas(newTop, kVertical);
00188    }
00189 }
00190 
00191 //______________________________________________________________________________
00192 void TGView::DrawRegion(Int_t, Int_t, UInt_t, UInt_t)
00193 {
00194    // Draw region.
00195 
00196    return;
00197 }
00198 
00199 //______________________________________________________________________________
00200 void TGView::UpdateRegion(Int_t x, Int_t y, UInt_t w, UInt_t h)
00201 {
00202    // update a part of view
00203 
00204    x = x < 0 ? 0 : x;
00205    y = y < 0 ? 0 : y;
00206 
00207    w = x + w > fCanvas->GetWidth() ? fCanvas->GetWidth() - x : w;
00208    h = y + h > fCanvas->GetHeight() ? fCanvas->GetHeight() - y : h;
00209 
00210    if (fExposedRegion.IsEmpty()) {
00211       fExposedRegion.fX = x;
00212       fExposedRegion.fY = y;
00213       fExposedRegion.fW = w;
00214       fExposedRegion.fH = h;
00215    } else {
00216       TGRectangle r(x, y, w, h);
00217       fExposedRegion.Merge(r);
00218    }
00219 
00220    fClient->NeedRedraw(this);
00221 }
00222 
00223 //______________________________________________________________________________
00224 void TGView::UpdateBackgroundStart()
00225 {
00226    // set some gc values
00227 
00228    fWhiteGC.SetTileStipXOrigin(-fVisible.fX);
00229    fWhiteGC.SetTileStipYOrigin(-fVisible.fY);
00230 }
00231 
00232 //______________________________________________________________________________
00233 Bool_t TGView::HandleButton(Event_t *event)
00234 {
00235    // handle button
00236 
00237    if (event->fType == kButtonPress) {
00238       int amount, ch;
00239 
00240       ch = fCanvas->GetHeight();
00241 
00242       if (fScrollVal.fY == 1) {
00243          amount = fScrollVal.fY * TMath::Max(ch/6, 1);
00244       } else {
00245          amount = fScrollVal.fY * 5;
00246       }
00247 
00248       if (event->fState & kKeyShiftMask) {
00249          amount = fScrollVal.fY;
00250       } else if (event->fState & kKeyControlMask) {
00251          amount = ch - TMath::Max(ch / 20, 1);
00252       }
00253 
00254       if (event->fCode == kButton4) {
00255          ScrollDown(amount);
00256          return kTRUE;
00257       } else if (event->fCode == kButton5) {
00258          ScrollUp(amount);
00259          return kTRUE;
00260       }
00261    }
00262    return kFALSE;
00263 }
00264 
00265 //______________________________________________________________________________
00266 void TGView::DoRedraw()
00267 {
00268    // redraw
00269 
00270    DrawBorder();
00271 
00272    if (!fExposedRegion.IsEmpty()) {
00273       DrawRegion(fExposedRegion.fX, fExposedRegion.fY, 
00274                  fExposedRegion.fW, fExposedRegion.fH);
00275       fExposedRegion.Empty();
00276    }
00277 }
00278 
00279 //______________________________________________________________________________
00280 Bool_t TGView::HandleExpose(Event_t *event)
00281 {
00282    // Handle expose events.
00283 
00284    if (event->fWindow == fCanvas->GetId()) {
00285 
00286       TGPosition pos(event->fX, event->fY);
00287       TGDimension dim(event->fWidth, event->fHeight);
00288       TGRectangle rect(pos, dim);
00289 
00290       if (fExposedRegion.IsEmpty()) {
00291          fExposedRegion = rect;
00292       } else {
00293          if (((!rect.fX && !fExposedRegion.fY) || 
00294               (!rect.fY && !fExposedRegion.fX)) && 
00295              ((rect.fX >= (int)fExposedRegion.fW) || 
00296               (rect.fY >= (int)fExposedRegion.fH))) {
00297             DrawRegion(rect.fX, rect.fY, rect.fW, rect.fY);
00298          } else {
00299             fExposedRegion.Merge(rect);
00300          }
00301       }
00302 
00303       fClient->NeedRedraw(this);
00304    } else {
00305       return TGCompositeFrame::HandleExpose(event);
00306    }
00307 
00308    return kTRUE;
00309 }
00310 
00311 //______________________________________________________________________________
00312 Bool_t TGView::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
00313 {
00314    // Process scrollbar messages.
00315 
00316    switch(GET_MSG(msg)) {
00317       case kC_HSCROLL:
00318          switch(GET_SUBMSG(msg)) {
00319             case kSB_SLIDERTRACK:
00320             case kSB_SLIDERPOS:
00321                SetVisibleStart(Int_t(parm1 * fScrollVal.fX), kHorizontal);
00322                break;
00323          }
00324          break;
00325 
00326       case kC_VSCROLL:
00327          switch(GET_SUBMSG(msg)) {
00328             case kSB_SLIDERTRACK:
00329             case kSB_SLIDERPOS:
00330                SetVisibleStart(Int_t(parm1 * fScrollVal.fY), kVertical);
00331                break;
00332          }
00333          break;
00334 
00335       default:
00336          break;
00337    }
00338    return kTRUE;
00339 }
00340 
00341 //______________________________________________________________________________
00342 void TGView::Layout()
00343 {
00344    // layout view
00345 
00346    Bool_t need_vsb, need_hsb;
00347    Int_t cw, ch;
00348 
00349    need_vsb = need_hsb = kFALSE;
00350 
00351    // test whether we need scrollbars
00352    cw = fWidth - (fBorderWidth << 1) - fXMargin - 1;
00353    ch = fHeight - (fBorderWidth << 1) - fYMargin - 1;
00354 
00355    fCanvas->SetWidth(cw);
00356    fCanvas->SetHeight(ch);
00357    ItemLayout();
00358 
00359    if ((Int_t)fVirtualSize.fWidth > cw) {
00360       if (fHsb) {
00361          need_hsb = kTRUE;
00362          if (fVsb) ch -= fVsb->GetDefaultWidth();
00363          if (ch < 0) ch = 0;
00364          fCanvas->SetHeight(ch);
00365          ItemLayout();
00366       }
00367    }
00368 
00369    if ((Int_t)fVirtualSize.fHeight > ch) {
00370       if (fVsb) {
00371          need_vsb = kTRUE;
00372          if (fHsb) cw -= fHsb->GetDefaultHeight();
00373          if (cw < 0) cw = 0;
00374          fCanvas->SetWidth(cw);
00375          ItemLayout();
00376       }
00377    }
00378 
00379    // re-check again (putting the scrollbar could have changed things)
00380 
00381    if ((Int_t)fVirtualSize.fWidth > cw) {
00382       if (!need_hsb) {
00383          need_hsb = kTRUE;
00384          if (fVsb) ch -= fVsb->GetDefaultWidth();
00385          if (ch < 0) ch = 0;
00386          fCanvas->SetHeight(ch);
00387          ItemLayout();
00388       }
00389    }
00390 
00391    if (fHsb) {
00392       if (need_hsb) {
00393          fHsb->MoveResize(fBorderWidth + fXMargin, ch + fBorderWidth + fYMargin,
00394                           cw, fHsb->GetDefaultHeight());
00395          fHsb->MapRaised();
00396       } else {
00397          fHsb->UnmapWindow();
00398          fHsb->SetPosition(0);
00399       }
00400    }
00401 
00402    if (fVsb) {
00403       if (need_vsb) {
00404          fVsb->MoveResize(cw + fBorderWidth + fXMargin,  fBorderWidth + fYMargin,
00405                           fVsb->GetDefaultWidth(), ch);
00406          fVsb->MapWindow();
00407       } else {
00408          fVsb->UnmapWindow();
00409          fVsb->SetPosition(0);
00410       }
00411    }
00412    fCanvas->MoveResize(fBorderWidth + fXMargin, fBorderWidth + fYMargin, cw, ch);
00413 
00414    if (fHsb) {
00415       fHsb->SetRange(fVirtualSize.fWidth / fScrollVal.fX, fCanvas->GetWidth() / fScrollVal.fX);
00416    }
00417 
00418    if (fVsb) {
00419       fVsb->SetRange(fVirtualSize.fHeight / fScrollVal.fY, fCanvas->GetHeight() / fScrollVal.fY);
00420    }
00421 }
00422 
00423 //______________________________________________________________________________
00424 void TGView::DrawBorder()
00425 {
00426    // Draw the border of the text edit widget.
00427 
00428    switch (fOptions & (kSunkenFrame | kRaisedFrame | kDoubleBorder)) {
00429       case kSunkenFrame | kDoubleBorder:
00430          gVirtualX->DrawLine(fId, GetShadowGC()(), 0, 0, fWidth-2, 0);
00431          gVirtualX->DrawLine(fId, GetShadowGC()(), 0, 0, 0, fHeight-2);
00432          gVirtualX->DrawLine(fId, GetBlackGC()(), 1, 1, fWidth-3, 1);
00433          gVirtualX->DrawLine(fId, GetBlackGC()(), 1, 1, 1, fHeight-3);
00434 
00435          gVirtualX->DrawLine(fId, GetHilightGC()(), 0, fHeight-1, fWidth-1, fHeight-1);
00436          gVirtualX->DrawLine(fId, GetHilightGC()(), fWidth-1, fHeight-1, fWidth-1, 0);
00437          gVirtualX->DrawLine(fId, GetBckgndGC()(),  1, fHeight-2, fWidth-2, fHeight-2);
00438          gVirtualX->DrawLine(fId, GetBckgndGC()(),  fWidth-2, 1, fWidth-2, fHeight-2);
00439          break;
00440 
00441       default:
00442          TGFrame::DrawBorder();
00443          break;
00444    }
00445 }
00446 
00447 //______________________________________________________________________________
00448 void TGView::ScrollToPosition(TGLongPosition pos)
00449 {
00450    // Scroll the canvas to pos.
00451 
00452    if (pos.fX < 0) pos.fX = 0;
00453    if (pos.fY < 0) pos.fY = 0;
00454    if (pos.fX != fHsb->GetPosition()) fHsb->SetPosition(pos.fX / fScrollVal.fX);
00455    if (pos.fY != fVsb->GetPosition()) fVsb->SetPosition(pos.fY / fScrollVal.fY);
00456 }
00457 
00458 //______________________________________________________________________________
00459 void TGView::ScrollCanvas(Int_t new_top, Int_t direction)
00460 {
00461    // Scroll the canvas to new_top in the kVertical or kHorizontal direction.
00462 
00463    Point_t points[4];
00464    Int_t xsrc, ysrc, xdest, ydest, cpyheight, cpywidth;
00465 
00466    if (new_top < 0) {
00467       return;
00468    }
00469 
00470    if (direction == kVertical) {
00471       if (new_top == fVisible.fY) {
00472          return;
00473       } 
00474 
00475       points[0].fX = points[3].fX = 0;
00476       points[1].fX = points[2].fX = fCanvas->GetWidth();
00477       xsrc = xdest = 0;
00478       cpywidth = 0;
00479       if (new_top < fVisible.fY) {
00480          ysrc = 0;
00481          ydest = Int_t(fVisible.fY - new_top);
00482          cpyheight = ydest;
00483          if (ydest > (Int_t)fCanvas->GetHeight()) {
00484             ydest = fCanvas->GetHeight();
00485          }
00486 
00487          points[1].fY = points[0].fY = 0;
00488          points[3].fY = points[2].fY = ydest; // -1;
00489       } else {
00490          ydest = 0;
00491          ysrc = Int_t(new_top - fVisible.fY);
00492          cpyheight= ysrc;
00493          if (ysrc > (Int_t)fCanvas->GetHeight()) {
00494             ysrc = fCanvas->GetHeight();
00495          }
00496          points[1].fY = points[0].fY = fCanvas->GetHeight()-ysrc; // +1;
00497          points[3].fY = points[2].fY = fCanvas->GetHeight();
00498       }
00499       fVisible.fY = new_top;
00500 
00501       if (fVisible.fY < 0) {
00502          fVisible.fY = 0;
00503       }
00504    } else {
00505       if (new_top == fVisible.fX) {
00506          return;
00507       }
00508 
00509       points[0].fY = points[1].fY = 0;
00510       points[2].fY = points[3].fY = fCanvas->GetHeight();
00511       ysrc = ydest = 0;
00512       cpyheight = 0;
00513 
00514       if (new_top < fVisible.fX) {
00515          xsrc = 0;
00516          xdest = Int_t(fVisible.fX - new_top);
00517          cpywidth = xdest;
00518          if (xdest < 0) {
00519             xdest = fCanvas->GetWidth();
00520          }
00521          points[0].fX = points[3].fX = 0;
00522          points[1].fX = points[2].fX = xdest ; // -1;
00523       } else {
00524          xdest = 0;
00525          xsrc =  Int_t(new_top - fVisible.fX);
00526          cpywidth = xsrc;
00527          if (xsrc > (Int_t)fCanvas->GetWidth()) {
00528             xsrc = fCanvas->GetWidth();
00529          }
00530          points[0].fX = points[3].fX = fCanvas->GetWidth()-xsrc; // +1;
00531          points[1].fX = points[2].fX = fCanvas->GetWidth();
00532       }
00533       fVisible.fX = new_top;
00534       if (fVisible.fX < 0) {
00535          fVisible.fX = 0;
00536       }
00537    }
00538 
00539    UpdateBackgroundStart();
00540 
00541    // Copy the scrolled region to its new position
00542    gVirtualX->CopyArea(fCanvas->GetId(), fCanvas->GetId(), fWhiteGC(),
00543                        xsrc, ysrc, fCanvas->GetWidth()-cpywidth,
00544                        fCanvas->GetHeight()-cpyheight, xdest, ydest);
00545 
00546    UInt_t xdiff = points[2].fX - points[0].fX;
00547    UInt_t ydiff = points[2].fY - points[0].fY;
00548 
00549    // under windows we need to redraw larger area (why?)
00550 #ifdef WIN32
00551    xdiff = xdiff << 1;
00552    ydiff = ydiff << 1;
00553 #endif
00554 
00555    DrawRegion(points[0].fX, points[0].fY, xdiff, ydiff);
00556 }
00557 
00558 //______________________________________________________________________________
00559 void TGView::ChangeBackground(Pixel_t col)
00560 {
00561    // Change background color of the canvas frame.
00562 
00563    fCanvas->SetBackgroundColor(col);
00564    fWhiteGC.SetBackground(col);
00565    fWhiteGC.SetForeground(col);
00566    DrawRegion(0, 0, fCanvas->GetWidth(), fCanvas->GetHeight());
00567 }
00568 
00569 //______________________________________________________________________________
00570 void TGView::SetBackgroundColor(Pixel_t col)
00571 {
00572    // Set background color of the canvas frame.
00573 
00574    fCanvas->SetBackgroundColor(col);
00575    fWhiteGC.SetBackground(col);
00576    fWhiteGC.SetForeground(col);
00577 }
00578 
00579 //______________________________________________________________________________
00580 void TGView::SetBackgroundPixmap(Pixmap_t p)
00581 {
00582    // Set backgound  pixmap
00583 
00584    fCanvas->SetBackgroundPixmap(p);
00585 }

Generated on Tue Jul 5 14:22:06 2011 for ROOT_528-00b_version by  doxygen 1.5.1