// @(#)root/gui:$Id$
// Author: Reiner Rohlfs   30/09/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.             *
 *************************************************************************/

#ifndef ROOT_TGDoubleSlider
#define ROOT_TGDoubleSlider


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGDoubleSlider, TGDoubleVSlider and TGDoubleHSlider                  //
//                                                                      //
// DoubleSlider widgets allow easy selection of a min and a max value   //
// out of a range.                                                      //
// DoubleSliders can be either horizontal or vertical oriented and      //
// there is a choice of three different types of tick marks.            //
//                                                                      //
// To change the min value press the mouse near to the left / bottom    //
// edge of the slider.                                                  //
// To change the max value press the mouse near to the right / top      //
// edge of the slider.                                                  //
// To change both values simultaneously press the mouse near to the     //
// center of the slider.                                                //
//                                                                      //
// TGDoubleSlider is an abstract base class. Use the concrete           //
// TGDoubleVSlider and TGDoubleHSlider.                                 //
//                                                                      //
// Dragging the slider will generate the event:                         //
// kC_VSLIDER, kSL_POS, slider id, 0  (for vertical slider)             //
// kC_HSLIDER, kSL_POS, slider id, 0  (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)       //
//                                                                      //
// Use the functions GetMinPosition(), GetMaxPosition() and             //
// GetPosition() to retrieve the position of the slider.                //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TGFrame
#include "TGFrame.h"
#endif
#ifndef ROOT_TGWidget
#include "TGWidget.h"
#endif

class TGPicture;

enum EDoubleSliderSize {
   //--- sizes for vert. and horz. sliders
   kDoubleSliderWidth  = 24,
   kDoubleSliderHeight = kDoubleSliderWidth
};


enum EDoubleSliderScale {
   //--- type of slider scale
   kDoubleScaleNo        = BIT(0),
   kDoubleScaleDownRight = BIT(1),
   kDoubleScaleBoth      = BIT(2)
};


class TGDoubleSlider : public TGFrame, public TGWidget {

private:
   TGDoubleSlider(const TGDoubleSlider&); // Not implemented
   TGDoubleSlider& operator=(const TGDoubleSlider&); // Not implemented

protected:
   Float_t       fPos;           // logical position between fVmin and fVmax
   Float_t       fSmin;          // logical position of min value of Slider
   Float_t       fSmax;          // logical position of max value of Slider
   Int_t         fRelPos;        // slider position in pixel coordinates
   Float_t       fVmin;          // logical lower limit of slider
   Float_t       fVmax;          // logical upper limit of slider
   Int_t         fScale;         // tick mark scale
   Int_t         fScaleType;     // tick mark scale type (no, downright, both)
   Int_t         fPressPoint;    // mouse position at button press event
   Float_t       fPressSmin;     // logical min position at button press event
   Float_t       fPressSmax;     // logical max position at button press event
   Int_t         fMove;          // 1: move min value
                                 // 2: move max value
                                 // 3: move min and max value
                                 // 0: don't move any value
   Bool_t        fReversedScale; // reverse which end is min and max
   Bool_t        fMarkEnds;      // lines marking where stretch zones begin
   const TGPicture *fSliderPic;  // picture to draw slider ends

   TString       GetSString() const; // returns scaling type as string

   static void   FixBounds(Float_t &min, Float_t &max);
   void          ChangeCursor(Event_t *event);

public:
   TGDoubleSlider(const TGWindow *p = 0, UInt_t w = 1, UInt_t h = 1, UInt_t type = 1, Int_t id = -1,
                  UInt_t options = kChildFrame,
                  Pixel_t back = GetDefaultFrameBackground(),
                  Bool_t reversed = kFALSE,
                  Bool_t mark_ends = kFALSE);

   virtual ~TGDoubleSlider() { }

   virtual Bool_t HandleButton(Event_t *event) = 0;
   virtual Bool_t HandleMotion(Event_t *event) = 0;

   virtual void  SetScale(Int_t scale) { fScale = scale; }
   virtual void  SetRange(Float_t min, Float_t max) {
      fVmin = min; fVmax = max;
      FixBounds(fVmin, fVmax);
   }

   virtual void SetPosition(Float_t min, Float_t max) {
      if (fReversedScale) { fSmin = fVmin+fVmax-max; fSmax = fVmin+fVmax-min; }
      else { fSmin = min; fSmax = max; }
      fClient->NeedRedraw(this);
   }

   virtual Float_t GetMinPosition() const {
      if (fReversedScale) return fVmin+fVmax-fSmax;
      else return fSmin;
   }
   virtual Float_t GetMaxPosition() const {
      if (fReversedScale) return fVmin+fVmax-fSmin;
      else return fSmax;
   }
   virtual void GetPosition(Float_t &min, Float_t &max) const {
      if (fReversedScale) { min = fVmin+fVmax-fSmax; max = fVmin+fVmax-fSmin; }
      else { min = fSmin; max = fSmax; }
   }
   virtual void GetPosition(Float_t *min, Float_t *max) const {
      if (fReversedScale) { *min = fVmin+fVmax-fSmax; *max = fVmin+fVmax-fSmin; }
      else { *min = fSmin; *max = fSmax; }
   }

   virtual void  MapSubwindows() { TGWindow::MapSubwindows(); }

   virtual void  PositionChanged() { Emit("PositionChanged()"); } //*SIGNAL*
   virtual void  Pressed() { Emit("Pressed()"); }                 //*SIGNAL*
   virtual void  Released() { Emit("Released()"); }               //*SIGNAL*

   ClassDef(TGDoubleSlider,0)  // Double slider widget abstract base class
};


class TGDoubleVSlider : public TGDoubleSlider {

protected:
   Int_t   fYp;      // vertical slider y position in pixel coordinates

   virtual void DoRedraw();

public:
   TGDoubleVSlider(const TGWindow *p = 0, UInt_t h = 1, UInt_t type = 1, Int_t id = -1,
                   UInt_t options = kVerticalFrame,
                   Pixel_t back = GetDefaultFrameBackground(),
                   Bool_t reversed = kFALSE,
                   Bool_t mark_ends = kFALSE);

   virtual ~TGDoubleVSlider();

   virtual Bool_t HandleButton(Event_t *event);
   virtual Bool_t HandleMotion(Event_t *event);
   virtual TGDimension GetDefaultSize() const
                     { return TGDimension(kDoubleSliderWidth, fHeight); }
   virtual void   SavePrimitive(std::ostream &out, Option_t *option = "");

   ClassDef(TGDoubleVSlider,0)  // Vertical double slider widget
};


class TGDoubleHSlider : public TGDoubleSlider {

protected:
   Int_t       fXp;     // horizontal slider x position in pixel coordinates

   virtual void DoRedraw();

public:
   TGDoubleHSlider(const TGWindow *p = 0, UInt_t w = 1, UInt_t type = 1, Int_t id = -1,
                   UInt_t options = kHorizontalFrame,
                   Pixel_t back = GetDefaultFrameBackground(),
                   Bool_t reversed = kFALSE,
                   Bool_t mark_ends = kFALSE);

   virtual ~TGDoubleHSlider();

   virtual Bool_t HandleButton(Event_t *event);
   virtual Bool_t HandleMotion(Event_t *event);
   virtual TGDimension GetDefaultSize() const
                     { return TGDimension(fWidth, kDoubleSliderHeight); }
   virtual void   SavePrimitive(std::ostream &out, Option_t *option = "");

   ClassDef(TGDoubleHSlider,0)  // Horizontal double slider widget
};

#endif
 TGDoubleSlider.h:1
 TGDoubleSlider.h:2
 TGDoubleSlider.h:3
 TGDoubleSlider.h:4
 TGDoubleSlider.h:5
 TGDoubleSlider.h:6
 TGDoubleSlider.h:7
 TGDoubleSlider.h:8
 TGDoubleSlider.h:9
 TGDoubleSlider.h:10
 TGDoubleSlider.h:11
 TGDoubleSlider.h:12
 TGDoubleSlider.h:13
 TGDoubleSlider.h:14
 TGDoubleSlider.h:15
 TGDoubleSlider.h:16
 TGDoubleSlider.h:17
 TGDoubleSlider.h:18
 TGDoubleSlider.h:19
 TGDoubleSlider.h:20
 TGDoubleSlider.h:21
 TGDoubleSlider.h:22
 TGDoubleSlider.h:23
 TGDoubleSlider.h:24
 TGDoubleSlider.h:25
 TGDoubleSlider.h:26
 TGDoubleSlider.h:27
 TGDoubleSlider.h:28
 TGDoubleSlider.h:29
 TGDoubleSlider.h:30
 TGDoubleSlider.h:31
 TGDoubleSlider.h:32
 TGDoubleSlider.h:33
 TGDoubleSlider.h:34
 TGDoubleSlider.h:35
 TGDoubleSlider.h:36
 TGDoubleSlider.h:37
 TGDoubleSlider.h:38
 TGDoubleSlider.h:39
 TGDoubleSlider.h:40
 TGDoubleSlider.h:41
 TGDoubleSlider.h:42
 TGDoubleSlider.h:43
 TGDoubleSlider.h:44
 TGDoubleSlider.h:45
 TGDoubleSlider.h:46
 TGDoubleSlider.h:47
 TGDoubleSlider.h:48
 TGDoubleSlider.h:49
 TGDoubleSlider.h:50
 TGDoubleSlider.h:51
 TGDoubleSlider.h:52
 TGDoubleSlider.h:53
 TGDoubleSlider.h:54
 TGDoubleSlider.h:55
 TGDoubleSlider.h:56
 TGDoubleSlider.h:57
 TGDoubleSlider.h:58
 TGDoubleSlider.h:59
 TGDoubleSlider.h:60
 TGDoubleSlider.h:61
 TGDoubleSlider.h:62
 TGDoubleSlider.h:63
 TGDoubleSlider.h:64
 TGDoubleSlider.h:65
 TGDoubleSlider.h:66
 TGDoubleSlider.h:67
 TGDoubleSlider.h:68
 TGDoubleSlider.h:69
 TGDoubleSlider.h:70
 TGDoubleSlider.h:71
 TGDoubleSlider.h:72
 TGDoubleSlider.h:73
 TGDoubleSlider.h:74
 TGDoubleSlider.h:75
 TGDoubleSlider.h:76
 TGDoubleSlider.h:77
 TGDoubleSlider.h:78
 TGDoubleSlider.h:79
 TGDoubleSlider.h:80
 TGDoubleSlider.h:81
 TGDoubleSlider.h:82
 TGDoubleSlider.h:83
 TGDoubleSlider.h:84
 TGDoubleSlider.h:85
 TGDoubleSlider.h:86
 TGDoubleSlider.h:87
 TGDoubleSlider.h:88
 TGDoubleSlider.h:89
 TGDoubleSlider.h:90
 TGDoubleSlider.h:91
 TGDoubleSlider.h:92
 TGDoubleSlider.h:93
 TGDoubleSlider.h:94
 TGDoubleSlider.h:95
 TGDoubleSlider.h:96
 TGDoubleSlider.h:97
 TGDoubleSlider.h:98
 TGDoubleSlider.h:99
 TGDoubleSlider.h:100
 TGDoubleSlider.h:101
 TGDoubleSlider.h:102
 TGDoubleSlider.h:103
 TGDoubleSlider.h:104
 TGDoubleSlider.h:105
 TGDoubleSlider.h:106
 TGDoubleSlider.h:107
 TGDoubleSlider.h:108
 TGDoubleSlider.h:109
 TGDoubleSlider.h:110
 TGDoubleSlider.h:111
 TGDoubleSlider.h:112
 TGDoubleSlider.h:113
 TGDoubleSlider.h:114
 TGDoubleSlider.h:115
 TGDoubleSlider.h:116
 TGDoubleSlider.h:117
 TGDoubleSlider.h:118
 TGDoubleSlider.h:119
 TGDoubleSlider.h:120
 TGDoubleSlider.h:121
 TGDoubleSlider.h:122
 TGDoubleSlider.h:123
 TGDoubleSlider.h:124
 TGDoubleSlider.h:125
 TGDoubleSlider.h:126
 TGDoubleSlider.h:127
 TGDoubleSlider.h:128
 TGDoubleSlider.h:129
 TGDoubleSlider.h:130
 TGDoubleSlider.h:131
 TGDoubleSlider.h:132
 TGDoubleSlider.h:133
 TGDoubleSlider.h:134
 TGDoubleSlider.h:135
 TGDoubleSlider.h:136
 TGDoubleSlider.h:137
 TGDoubleSlider.h:138
 TGDoubleSlider.h:139
 TGDoubleSlider.h:140
 TGDoubleSlider.h:141
 TGDoubleSlider.h:142
 TGDoubleSlider.h:143
 TGDoubleSlider.h:144
 TGDoubleSlider.h:145
 TGDoubleSlider.h:146
 TGDoubleSlider.h:147
 TGDoubleSlider.h:148
 TGDoubleSlider.h:149
 TGDoubleSlider.h:150
 TGDoubleSlider.h:151
 TGDoubleSlider.h:152
 TGDoubleSlider.h:153
 TGDoubleSlider.h:154
 TGDoubleSlider.h:155
 TGDoubleSlider.h:156
 TGDoubleSlider.h:157
 TGDoubleSlider.h:158
 TGDoubleSlider.h:159
 TGDoubleSlider.h:160
 TGDoubleSlider.h:161
 TGDoubleSlider.h:162
 TGDoubleSlider.h:163
 TGDoubleSlider.h:164
 TGDoubleSlider.h:165
 TGDoubleSlider.h:166
 TGDoubleSlider.h:167
 TGDoubleSlider.h:168
 TGDoubleSlider.h:169
 TGDoubleSlider.h:170
 TGDoubleSlider.h:171
 TGDoubleSlider.h:172
 TGDoubleSlider.h:173
 TGDoubleSlider.h:174
 TGDoubleSlider.h:175
 TGDoubleSlider.h:176
 TGDoubleSlider.h:177
 TGDoubleSlider.h:178
 TGDoubleSlider.h:179
 TGDoubleSlider.h:180
 TGDoubleSlider.h:181
 TGDoubleSlider.h:182
 TGDoubleSlider.h:183
 TGDoubleSlider.h:184
 TGDoubleSlider.h:185
 TGDoubleSlider.h:186
 TGDoubleSlider.h:187
 TGDoubleSlider.h:188
 TGDoubleSlider.h:189
 TGDoubleSlider.h:190
 TGDoubleSlider.h:191
 TGDoubleSlider.h:192
 TGDoubleSlider.h:193
 TGDoubleSlider.h:194
 TGDoubleSlider.h:195
 TGDoubleSlider.h:196
 TGDoubleSlider.h:197
 TGDoubleSlider.h:198
 TGDoubleSlider.h:199
 TGDoubleSlider.h:200
 TGDoubleSlider.h:201
 TGDoubleSlider.h:202
 TGDoubleSlider.h:203
 TGDoubleSlider.h:204
 TGDoubleSlider.h:205
 TGDoubleSlider.h:206
 TGDoubleSlider.h:207
 TGDoubleSlider.h:208
 TGDoubleSlider.h:209