// @(#)root/gui:$Name: $:$Id: TGSlider.cxx,v 1.12 2005/11/17 19:09:28 rdm Exp $
// Author: Fons Rademakers 14/01/98
/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
/**************************************************************************
This source is based on Xclass95, a Win95-looking GUI toolkit.
Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
Xclass95 is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
**************************************************************************/
//////////////////////////////////////////////////////////////////////////
// //
// TGSlider, TGVSlider and TGHSlider //
// //
// Slider widgets allow easy selection of a range. //
// Sliders can be either horizontal or vertical oriented and there is //
// a choice of two different slider types and three different types //
// of tick marks. //
// //
// TGSlider is an abstract base class. Use the concrete TGVSlider and //
// TGHSlider. //
// //
// Dragging the slider will generate the event: //
// kC_VSLIDER, kSL_POS, slider id, position (for vertical slider) //
// kC_HSLIDER, kSL_POS, slider id, position (for horizontal slider) //
// //
// Pressing the mouse will generate the event: //
// kC_VSLIDER, kSL_PRESS, slider id, 0 (for vertical slider) //
// kC_HSLIDER, kSL_PRESS, slider id, 0 (for horizontal slider) //
// //
// Releasing the mouse will generate the event: //
// kC_VSLIDER, kSL_RELEASE, slider id, 0 (for vertical slider) //
// kC_HSLIDER, kSL_RELEASE, slider id, 0 (for horizontal slider) //
// //
//////////////////////////////////////////////////////////////////////////
#include "TGSlider.h"
#include "TGPicture.h"
#include "Riostream.h"
ClassImp(TGSlider)
ClassImp(TGVSlider)
ClassImp(TGHSlider)
//______________________________________________________________________________
TGSlider::TGSlider(const TGWindow *p, UInt_t w, UInt_t h, UInt_t type, Int_t id,
UInt_t options, ULong_t back)
: TGFrame(p, w, h, options, back)
{
// Slider constructor.
fWidgetId = id;
fWidgetFlags = kWidgetWantFocus;
fMsgWindow = p;
fType = type;
fScale = 10;
fDragging = kFALSE;
}
//______________________________________________________________________________
TGVSlider::TGVSlider(const TGWindow *p, UInt_t h, UInt_t type, Int_t id,
UInt_t options, ULong_t back) :
TGSlider(p, kSliderWidth, h, type, id, options, back)
{
// Create a vertical slider widget.
if ((fType & kSlider1))
fSliderPic = fClient->GetPicture("slider1h.xpm");
else
fSliderPic = fClient->GetPicture("slider2h.xpm");
if (!fSliderPic)
Error("TGVSlider", "slider?h.xpm not found");
gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
kButtonPressMask | kButtonReleaseMask |
kPointerMotionMask, kNone, kNone);
// set initial values
fPos = h/2; fVmin = 0; fVmax = h;
}
//______________________________________________________________________________
TGVSlider::~TGVSlider()
{
// Delete vertical slider widget.
if (fSliderPic) fClient->FreePicture(fSliderPic);
}
//______________________________________________________________________________
void TGVSlider::DoRedraw()
{
// Redraw vertical slider widget.
// cleanup the drawable
gVirtualX->ClearWindow(fId);
gVirtualX->DrawLine(fId, GetShadowGC()(), fWidth/2, 8, fWidth/2-1, 8);
gVirtualX->DrawLine(fId, GetShadowGC()(), fWidth/2-1, 8, fWidth/2-1, fHeight-9);
gVirtualX->DrawLine(fId, GetHilightGC()(), fWidth/2+1, 8, fWidth/2+1, fHeight-8);
gVirtualX->DrawLine(fId, GetHilightGC()(), fWidth/2+1, fHeight-8, fWidth/2, fHeight-8);
gVirtualX->DrawLine(fId, GetBlackGC()(), fWidth/2, 9, fWidth/2, fHeight-9);
// check scale
if (fScale == 1) fScale++;
if (fScale * 2 > (int)fHeight) fScale = 0;
if (fScale > 0 && !(fType & kScaleNo)) {
int lines = ((int)fHeight-16) / fScale;
int remain = ((int)fHeight-16) % fScale;
if (lines < 1) lines = 1;
for (int i = 0; i <= lines; i++) {
int y = i * fScale + (i * remain) / lines;
gVirtualX->DrawLine(fId, GetBlackGC()(), fWidth/2+8, y+7, fWidth/2+10, y+7);
if ((fType & kSlider2) && (fType & kScaleBoth))
gVirtualX->DrawLine(fId, GetBlackGC()(), fWidth/2-9, y+7, fWidth/2-11, y+7);
}
}
if (fPos < fVmin) fPos = fVmin;
if (fPos > fVmax) fPos = fVmax;
// calc slider-picture position
fRelPos = (((int)fHeight-16) * (fPos - fVmin)) / (fVmax - fVmin) + 8;
if (fSliderPic) fSliderPic->Draw(fId, GetBckgndGC()(), fWidth/2-7, fRelPos-6);
}
//______________________________________________________________________________
Bool_t TGVSlider::HandleButton(Event_t *event)
{
// Handle mouse button event in vertical slider.
if (event->fType == kButtonPress) {
// last argument kFALSE forces all specified events to this window
gVirtualX->GrabPointer(fId, kButtonPressMask | kButtonReleaseMask |
kPointerMotionMask, kNone, kNone,
kTRUE, kFALSE);
if (event->fY >= fRelPos - 7 && event->fY <= fRelPos + 7) {
// slider selected
fDragging = kTRUE;
fYp = event->fY - (fRelPos-7);
SendMessage(fMsgWindow, MK_MSG(kC_VSLIDER, kSL_PRESS), fWidgetId, 0);
fClient->ProcessLine(fCommand, MK_MSG(kC_VSLIDER, kSL_PRESS), fWidgetId, 0);
Pressed();
} else {
if (event->fCode == kButton1) {
// scroll up or down
int m = (fVmax - fVmin) / (fHeight-16);
if (event->fY < fRelPos) {
fPos -= ((m) ? m : 1);
}
if (event->fY > fRelPos) {
fPos += ((m) ? m : 1);
}
} else if (event->fCode == kButton2) {
// set absolute position
fPos = ((fVmax - fVmin) * event->fY) / (fHeight-16) + fVmin;
}
SendMessage(fMsgWindow, MK_MSG(kC_VSLIDER, kSL_POS),
fWidgetId, fPos);
fClient->ProcessLine(fCommand, MK_MSG(kC_VSLIDER, kSL_POS),
fWidgetId, fPos);
PositionChanged(fPos);
}
fClient->NeedRedraw(this);
} else {
// ButtonRelease
fDragging = kFALSE;
gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE); // ungrab pointer
SendMessage(fMsgWindow, MK_MSG(kC_VSLIDER, kSL_RELEASE), fWidgetId, 0);
fClient->ProcessLine(fCommand, MK_MSG(kC_VSLIDER, kSL_RELEASE), fWidgetId, 0);
Released();
}
return kTRUE;
}
//______________________________________________________________________________
Bool_t TGVSlider::HandleMotion(Event_t *event)
{
// Handle mouse motion event in vertical slider.
if (fDragging) {
int old = fPos;
fPos = ((fVmax - fVmin) * (event->fY - fYp)) / ((int)fHeight-16) + fVmin;
if (fPos > fVmax) fPos = fVmax;
if (fPos < fVmin) fPos = fVmin;
// check if position changed
if (old != fPos) {
fClient->NeedRedraw(this);
SendMessage(fMsgWindow, MK_MSG(kC_VSLIDER, kSL_POS),
fWidgetId, fPos);
fClient->ProcessLine(fCommand, MK_MSG(kC_VSLIDER, kSL_POS),
fWidgetId, fPos);
PositionChanged(fPos);
}
}
return kTRUE;
}
//______________________________________________________________________________
TGHSlider::TGHSlider(const TGWindow *p, UInt_t w, UInt_t type, Int_t id,
UInt_t options, ULong_t back) :
TGSlider(p, w, kSliderHeight, type, id, options, back)
{
// Create horizontal slider widget.
if ((fType & kSlider1))
fSliderPic = fClient->GetPicture("slider1v.xpm");
else
fSliderPic = fClient->GetPicture("slider2v.xpm");
if (!fSliderPic)
Error("TGHSlider", "slider?v.xpm not found");
gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
kButtonPressMask | kButtonReleaseMask |
kPointerMotionMask, kNone, kNone);
// set initial values
fPos = w/2; fVmin = 0; fVmax = w;
}
//______________________________________________________________________________
TGHSlider::~TGHSlider()
{
// Delete a horizontal slider widget.
if (fSliderPic) fClient->FreePicture(fSliderPic);
}
//______________________________________________________________________________
void TGHSlider::DoRedraw()
{
// Redraw horizontal slider widget.
// cleanup drawable
gVirtualX->ClearWindow(fId);
gVirtualX->DrawLine(fId, GetShadowGC()(), 8, fHeight/2, 8, fHeight/2-1);
gVirtualX->DrawLine(fId, GetShadowGC()(), 8, fHeight/2-1, fWidth-9, fHeight/2-1);
gVirtualX->DrawLine(fId, GetHilightGC()(), 8, fHeight/2+1, fWidth-8, fHeight/2+1);
gVirtualX->DrawLine(fId, GetHilightGC()(), fWidth-8, fHeight/2+1, fWidth-8, fHeight/2);
gVirtualX->DrawLine(fId, GetBlackGC()(), 9, fHeight/2, fWidth-9, fHeight/2);
if (fScale == 1) fScale++;
if (fScale * 2 > (int)fWidth) fScale = 0;
if (fScale > 0 && !(fType & kScaleNo)) {
int lines = ((int)fWidth-16) / fScale;
int remain = ((int)fWidth-16) % fScale;
if (lines < 1) lines = 1;
for (int i = 0; i <= lines; i++) {
int x = i * fScale + (i * remain) / lines;
gVirtualX->DrawLine(fId, GetBlackGC()(), x+7, fHeight/2+8, x+7, fHeight/2+10);
if ((fType & kSlider2) && (fType & kScaleBoth))
gVirtualX->DrawLine(fId, GetBlackGC()(), x+7, fHeight/2-9, x+7, fHeight/2-11);
}
}
if (fPos < fVmin) fPos = fVmin;
if (fPos > fVmax) fPos = fVmax;
// calc slider-picture position
fRelPos = (((int)fWidth-16) * (fPos - fVmin)) / (fVmax - fVmin) + 8;
if (fSliderPic) fSliderPic->Draw(fId, GetBckgndGC()(), fRelPos-6, fHeight/2-7);
}
//______________________________________________________________________________
Bool_t TGHSlider::HandleButton(Event_t *event)
{
// Handle mouse button event in horizontal slider widget.
if (event->fType == kButtonPress) {
if (event->fX >= fRelPos - 7 && event->fX <= fRelPos + 7) {
// slider selected
fDragging = kTRUE;
fXp = event->fX - (fRelPos-7);
SendMessage(fMsgWindow, MK_MSG(kC_HSLIDER, kSL_PRESS), fWidgetId, 0);
fClient->ProcessLine(fCommand, MK_MSG(kC_HSLIDER, kSL_PRESS), fWidgetId, 0);
Pressed();
} else {
if (event->fCode == kButton1) {
int m = (fVmax - fVmin) / (fWidth-16);
if (event->fX < fRelPos) {
fPos -= ((m) ? m : 1);
}
if (event->fX > fRelPos) {
fPos += ((m) ? m : 1);
}
} else if (event->fCode == kButton2) {
fPos = ((fVmax - fVmin) * event->fX) / (fWidth-16) + fVmin;
}
SendMessage(fMsgWindow, MK_MSG(kC_HSLIDER, kSL_POS),
fWidgetId, fPos);
fClient->ProcessLine(fCommand, MK_MSG(kC_HSLIDER, kSL_POS),
fWidgetId, fPos);
PositionChanged(fPos);
}
fClient->NeedRedraw(this);
// last argument kFALSE forces all specified events to this window
gVirtualX->GrabPointer(fId, kButtonPressMask | kButtonReleaseMask | kPointerMotionMask,
kNone, kNone, kTRUE, kFALSE);
} else {
// ButtonRelease
fDragging = kFALSE;
gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE); // ungrab pointer
SendMessage(fMsgWindow, MK_MSG(kC_HSLIDER, kSL_RELEASE), fWidgetId, 0);
fClient->ProcessLine(fCommand, MK_MSG(kC_HSLIDER, kSL_RELEASE), fWidgetId, 0);
Released();
}
return kTRUE;
}
//______________________________________________________________________________
Bool_t TGHSlider::HandleMotion(Event_t *event)
{
// Handle mouse motion event in horizontal slide widget.
if (fDragging) {
int old = fPos;
fPos = ((fVmax - fVmin) * (event->fX - fXp)) / ((int)fWidth-16) + fVmin;
if (fPos > fVmax) fPos = fVmax;
if (fPos < fVmin) fPos = fVmin;
// check if position changed
if (old != fPos) {
fClient->NeedRedraw(this);
SendMessage(fMsgWindow, MK_MSG(kC_HSLIDER, kSL_POS),
fWidgetId, fPos);
fClient->ProcessLine(fCommand, MK_MSG(kC_HSLIDER, kSL_POS),
fWidgetId, fPos);
PositionChanged(fPos);
}
}
return kTRUE;
}
//______________________________________________________________________________
TString TGSlider::GetTypeString() const
{
// Returns the slider type as a string - used in SavePrimitive().
TString stype;
if (fType) {
if (fType & kSlider1) {
if (stype.Length() == 0) stype = "kSlider1";
else stype += " | kSlider1";
}
if (fType & kSlider2) {
if (stype.Length() == 0) stype = "kSlider2";
else stype += " | kSlider2";
}
if (fType & kScaleNo) {
if (stype.Length() == 0) stype = "kScaleNo";
else stype += " | kScaleNo";
}
if (fType & kScaleDownRight) {
if (stype.Length() == 0) stype = "kScaleDownRight";
else stype += " | kScaleDownRight";
}
if (fType & kScaleBoth) {
if (stype.Length() == 0) stype = "kScaleBoth";
else stype += " | kScaleBoth";
}
}
return stype;
}
//______________________________________________________________________________
void TGHSlider::SavePrimitive(ofstream &out, Option_t *option)
{
// Save an horizontal slider as a C++ statement(s) on output stream out.
if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
out <<" TGHSlider *";
out << GetName() << " = new TGHSlider(" << fParent->GetName()
<< "," << GetWidth() << ",";
out << GetTypeString() << "," << WidgetId();
if (fBackground == GetDefaultFrameBackground()) {
if (!GetOptions()) {
out <<");" << endl;
} else {
out << "," << GetOptionString() <<");" << endl;
}
} else {
out << "," << GetOptionString() << ",ucolor);" << endl;
}
if (fVmin != 0 || fVmax != (Int_t)fWidth)
out << " " << GetName() <<"->SetRange(" << fVmin << "," << fVmax << ");" << endl;
if (fPos != (Int_t)fWidth/2)
out << " " << GetName() <<"->SetPosition(" << GetPosition() << ");" << endl;
if (fScale != 10)
out << " " << GetName() <<"->SetScale(" << fScale << ");" << endl;
}
//______________________________________________________________________________
void TGVSlider::SavePrimitive(ofstream &out, Option_t *option)
{
// Save an horizontal slider as a C++ statement(s) on output stream out.
if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
out<<" TGVSlider *";
out << GetName() <<" = new TGVSlider("<< fParent->GetName()
<< "," << GetHeight() << ",";
out << GetTypeString() << "," << WidgetId();
if (fBackground == GetDefaultFrameBackground()) {
if (!GetOptions()) {
out <<");" << endl;
} else {
out << "," << GetOptionString() <<");" << endl;
}
} else {
out << "," << GetOptionString() << ",ucolor);" << endl;
}
if (fVmin != 0 || fVmax != (Int_t)fHeight)
out << " " << GetName() <<"->SetRange(" << fVmin << "," << fVmax << ");" << endl;
if (fPos != (Int_t)fHeight/2)
out << " " << GetName() <<"->SetPosition(" << GetPosition() << ");" << endl;
if (fScale != 10)
out << " " << GetName() <<"->SetScale(" << fScale << ");" << endl;
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.