// @(#)root/gpad:$Id$
// Author: Rene Brun   23/11/96

/*************************************************************************
 * 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.             *
 *************************************************************************/

#include "Riostream.h"
#include "TROOT.h"
#include "TSlider.h"
#include "TSliderBox.h"

#include <string.h>

ClassImp(TSliderBox)

//______________________________________________________________________________
//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TSliderBox                                                           //
//                                                                      //
//  The moving box in a TSlider                                         //
//                                                                      //
//////////////////////////////////////////////////////////////////////////


//______________________________________________________________________________
TSliderBox::TSliderBox(): TWbox()
{
   // SliderBox default constructor.

   fSlider = 0;
}


//______________________________________________________________________________
TSliderBox::TSliderBox(Double_t x1, Double_t y1,Double_t x2, Double_t  y2, Color_t color, Short_t bordersize, Short_t bordermode)
           :TWbox(x1,y1,x2,y2,color,bordersize,bordermode)
{
   // SliderBox normal constructor.

   fSlider = 0;
}


//______________________________________________________________________________
TSliderBox::~TSliderBox()
{
   // SliderBox default destructor.
}


//______________________________________________________________________________
void TSliderBox::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
   // Interaction with a slider.

   const Int_t kMaxDiff = 5;
   const Int_t kMinSize = 20;

   static Int_t px1, px2, py1, py2, pxl, pyl, pxt, pyt, pxold, pyold;
   static Int_t px1p, px2p, py1p, py2p;
   static Bool_t  pL, pR, pTop, pBot, pINSIDE;
   Int_t  wx, wy;
   Bool_t doing_again = kFALSE;
   Bool_t opaque  = gPad->OpaqueMoving();
   Bool_t ropaque = gPad->OpaqueResizing();

   TVirtualPad  *parent = gPad;

   Int_t border   = parent->GetBorderSize();
   Int_t pxpadmin = parent->XtoAbsPixel(parent->GetX1()) + border;
   Int_t pxpadmax = parent->XtoAbsPixel(parent->GetX2()) - border;
   Int_t pypadmin = parent->YtoAbsPixel(parent->GetY1()) - border;
   Int_t pypadmax = parent->YtoAbsPixel(parent->GetY2()) + border;

   Bool_t vertical = kTRUE;
   if (pxpadmax-pxpadmin > pypadmin-pypadmax) vertical = kFALSE;

again:

   switch (event) {

   case kButton1Down:

      gVirtualX->SetLineColor(-1);
      TAttLine::Modify();  //Change line attributes only if necessary
      if (GetFillColor())
         gVirtualX->SetLineColor(GetFillColor());
      else
         gVirtualX->SetLineColor(1);
      gVirtualX->SetLineWidth(2);

      // No break !!!

   case kMouseMotion:

      px1 = gPad->XtoAbsPixel(GetX1());
      py1 = gPad->YtoAbsPixel(GetY1());
      px2 = gPad->XtoAbsPixel(GetX2());
      py2 = gPad->YtoAbsPixel(GetY2());

      if (px1 < px2) {
         pxl = px1;
         pxt = px2;
      } else {
         pxl = px2;
         pxt = px1;
      }
      if (py1 < py2) {
         pyl = py1;
         pyt = py2;
      } else {
         pyl = py2;
         pyt = py1;
      }

      px1p = pxpadmin;
      py1p = pypadmin;
      px2p = pxpadmax;
      py2p = pypadmax;

      pL = pR  = pTop = pBot = pINSIDE = kFALSE;

      if (vertical && (px > pxl+kMaxDiff && px < pxt-kMaxDiff) &&
          TMath::Abs(py - pyl) < kMaxDiff) {             // top edge
         pxold = pxl; pyold = pyl; pTop = kTRUE;
         gPad->SetCursor(kTopSide);
      }

      if (vertical && (px > pxl+kMaxDiff && px < pxt-kMaxDiff) &&
          TMath::Abs(py - pyt) < kMaxDiff) {             // bottom edge
         pxold = pxt; pyold = pyt; pBot = kTRUE;
         gPad->SetCursor(kBottomSide);
      }

      if (!vertical && (py > pyl+kMaxDiff && py < pyt-kMaxDiff) &&
          TMath::Abs(px - pxl) < kMaxDiff) {             // left edge
         pxold = pxl; pyold = pyl; pL = kTRUE;
         gPad->SetCursor(kLeftSide);
      }

      if (!vertical && (py > pyl+kMaxDiff && py < pyt-kMaxDiff) &&
          TMath::Abs(px - pxt) < kMaxDiff) {             // right edge
         pxold = pxt; pyold = pyt; pR = kTRUE;
         gPad->SetCursor(kRightSide);
      }

      if ((px > pxl+kMaxDiff && px < pxt-kMaxDiff) &&
          (py > pyl+kMaxDiff && py < pyt-kMaxDiff)) {    // inside box
         pxold = px; pyold = py; pINSIDE = kTRUE;
         if (event == kButton1Down)
            gPad->SetCursor(kMove);
         else
            gPad->SetCursor(kCross);
      }

      fResizing = kFALSE;
      if ( pL || pR || pTop || pBot)
         fResizing = kTRUE;

      if ( !pL && !pR && !pTop && !pBot && !pINSIDE)
         gPad->SetCursor(kCross);

      break;

   case kButton1Motion:

      wx = wy = 0;

      if (pTop) {
         if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
         py2 += py - pyold;
         if (py2 > py1-kMinSize) { py2 = py1-kMinSize; wy = py2; }
         if (py2 < py2p) { py2 = py2p; wy = py2; }
         if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
      }
      if (pBot) {
         if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
         py1 += py - pyold;
         if (py1 < py2+kMinSize) { py1 = py2+kMinSize; wy = py1; }
         if (py1 > py1p) { py1 = py1p; wy = py1; }
         if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
      }
      if (pL) {
         if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
         px1 += px - pxold;
         if (px1 > px2-kMinSize) { px1 = px2-kMinSize; wx = px1; }
         if (px1 < px1p) { px1 = px1p; wx = px1; }
         if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
      }
      if (pR) {
         if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
         px2 += px - pxold;
         if (px2 < px1+kMinSize) { px2 = px1+kMinSize; wx = px2; }
         if (px2 > px2p) { px2 = px2p; wx = px2; }
         if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
      }
      if (pINSIDE) {
         if (!opaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);  // draw the old box
         Int_t dx = px - pxold;
         Int_t dy = py - pyold;
         px1 += dx; py1 += dy; px2 += dx; py2 += dy;
         if (px1 < px1p) { dx = px1p - px1; px1 += dx; px2 += dx; wx = px+dx; }
         if (px2 > px2p) { dx = px2 - px2p; px1 -= dx; px2 -= dx; wx = px-dx; }
         if (py1 > py1p) { dy = py1 - py1p; py1 -= dy; py2 -= dy; wy = py-dy; }
         if (py2 < py2p) { dy = py2p - py2; py1 += dy; py2 += dy; wy = py+dy; }
         if (!opaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);  // draw the new box
      }

      if (wx || wy) {
         if (wx) px = wx;
         if (wy) py = wy;
         gVirtualX->Warp(px, py);
      }

      pxold = px;
      pyold = py;

      if ((pINSIDE && opaque) || (fResizing && ropaque)) {
         event = kButton1Up;
         doing_again = kTRUE;
         goto again;
      }

      break;

   case kButton1Up:

      if (pTop || pBot || pL || pR || pINSIDE) {
         fX1 = gPad->AbsPixeltoX(px1);
         fY1 = gPad->AbsPixeltoY(py1);
         fX2 = gPad->AbsPixeltoX(px2);
         fY2 = gPad->AbsPixeltoY(py2);
      }

      if (pINSIDE) {
         // if it was not a pad that was moved then it must have been
         // a box or something like that so we have to redraw the pad
         if (parent == gPad) gPad->Modified(kTRUE);
         if (!doing_again) gPad->SetCursor(kCross);
      }

      if (pTop || pBot ||  pL || pR )
         gPad->Modified(kTRUE);

      // Restore original event type
      if (doing_again)
         event = kButton1Motion;
      else {
         gVirtualX->SetLineColor(-1);
         gVirtualX->SetLineWidth(-1);
      }

      break;
   }


   // Give control to object using the slider

   Float_t xpmin,xpmax;
   if (vertical) {
      xpmin = Float_t(pypadmin-py1)/Float_t(pypadmin-pypadmax);
      xpmax = Float_t(pypadmin-py2)/Float_t(pypadmin-pypadmax);
   } else {  //vertical slider
      xpmin = Float_t(px1-pxpadmin)/Float_t(pxpadmax-pxpadmin);
      xpmax = Float_t(px2-pxpadmin)/Float_t(pxpadmax-pxpadmin);
   }
   fSlider->SetMinimum(xpmin);
   fSlider->SetMaximum(xpmax);

   //A user method to execute?
   Int_t lenMethod = strlen(fSlider->GetMethod());
   if (event == kButton1Up && lenMethod > 0 ) {
      gPad->SetCursor(kWatch);
      gROOT->ProcessLine(fSlider->GetMethod());
      return;
   }

   //An object connected to this slider?
   TObject *obj = fSlider->GetObject();
   if (obj) {
      obj->ExecuteEvent(event,0,0);
   }
}


//______________________________________________________________________________
void TSliderBox::SavePrimitive(std::ostream &, Option_t * /*= ""*/)
{
    // Save primitive as a C++ statement(s) on output stream out
}
 TSliderBox.cxx:1
 TSliderBox.cxx:2
 TSliderBox.cxx:3
 TSliderBox.cxx:4
 TSliderBox.cxx:5
 TSliderBox.cxx:6
 TSliderBox.cxx:7
 TSliderBox.cxx:8
 TSliderBox.cxx:9
 TSliderBox.cxx:10
 TSliderBox.cxx:11
 TSliderBox.cxx:12
 TSliderBox.cxx:13
 TSliderBox.cxx:14
 TSliderBox.cxx:15
 TSliderBox.cxx:16
 TSliderBox.cxx:17
 TSliderBox.cxx:18
 TSliderBox.cxx:19
 TSliderBox.cxx:20
 TSliderBox.cxx:21
 TSliderBox.cxx:22
 TSliderBox.cxx:23
 TSliderBox.cxx:24
 TSliderBox.cxx:25
 TSliderBox.cxx:26
 TSliderBox.cxx:27
 TSliderBox.cxx:28
 TSliderBox.cxx:29
 TSliderBox.cxx:30
 TSliderBox.cxx:31
 TSliderBox.cxx:32
 TSliderBox.cxx:33
 TSliderBox.cxx:34
 TSliderBox.cxx:35
 TSliderBox.cxx:36
 TSliderBox.cxx:37
 TSliderBox.cxx:38
 TSliderBox.cxx:39
 TSliderBox.cxx:40
 TSliderBox.cxx:41
 TSliderBox.cxx:42
 TSliderBox.cxx:43
 TSliderBox.cxx:44
 TSliderBox.cxx:45
 TSliderBox.cxx:46
 TSliderBox.cxx:47
 TSliderBox.cxx:48
 TSliderBox.cxx:49
 TSliderBox.cxx:50
 TSliderBox.cxx:51
 TSliderBox.cxx:52
 TSliderBox.cxx:53
 TSliderBox.cxx:54
 TSliderBox.cxx:55
 TSliderBox.cxx:56
 TSliderBox.cxx:57
 TSliderBox.cxx:58
 TSliderBox.cxx:59
 TSliderBox.cxx:60
 TSliderBox.cxx:61
 TSliderBox.cxx:62
 TSliderBox.cxx:63
 TSliderBox.cxx:64
 TSliderBox.cxx:65
 TSliderBox.cxx:66
 TSliderBox.cxx:67
 TSliderBox.cxx:68
 TSliderBox.cxx:69
 TSliderBox.cxx:70
 TSliderBox.cxx:71
 TSliderBox.cxx:72
 TSliderBox.cxx:73
 TSliderBox.cxx:74
 TSliderBox.cxx:75
 TSliderBox.cxx:76
 TSliderBox.cxx:77
 TSliderBox.cxx:78
 TSliderBox.cxx:79
 TSliderBox.cxx:80
 TSliderBox.cxx:81
 TSliderBox.cxx:82
 TSliderBox.cxx:83
 TSliderBox.cxx:84
 TSliderBox.cxx:85
 TSliderBox.cxx:86
 TSliderBox.cxx:87
 TSliderBox.cxx:88
 TSliderBox.cxx:89
 TSliderBox.cxx:90
 TSliderBox.cxx:91
 TSliderBox.cxx:92
 TSliderBox.cxx:93
 TSliderBox.cxx:94
 TSliderBox.cxx:95
 TSliderBox.cxx:96
 TSliderBox.cxx:97
 TSliderBox.cxx:98
 TSliderBox.cxx:99
 TSliderBox.cxx:100
 TSliderBox.cxx:101
 TSliderBox.cxx:102
 TSliderBox.cxx:103
 TSliderBox.cxx:104
 TSliderBox.cxx:105
 TSliderBox.cxx:106
 TSliderBox.cxx:107
 TSliderBox.cxx:108
 TSliderBox.cxx:109
 TSliderBox.cxx:110
 TSliderBox.cxx:111
 TSliderBox.cxx:112
 TSliderBox.cxx:113
 TSliderBox.cxx:114
 TSliderBox.cxx:115
 TSliderBox.cxx:116
 TSliderBox.cxx:117
 TSliderBox.cxx:118
 TSliderBox.cxx:119
 TSliderBox.cxx:120
 TSliderBox.cxx:121
 TSliderBox.cxx:122
 TSliderBox.cxx:123
 TSliderBox.cxx:124
 TSliderBox.cxx:125
 TSliderBox.cxx:126
 TSliderBox.cxx:127
 TSliderBox.cxx:128
 TSliderBox.cxx:129
 TSliderBox.cxx:130
 TSliderBox.cxx:131
 TSliderBox.cxx:132
 TSliderBox.cxx:133
 TSliderBox.cxx:134
 TSliderBox.cxx:135
 TSliderBox.cxx:136
 TSliderBox.cxx:137
 TSliderBox.cxx:138
 TSliderBox.cxx:139
 TSliderBox.cxx:140
 TSliderBox.cxx:141
 TSliderBox.cxx:142
 TSliderBox.cxx:143
 TSliderBox.cxx:144
 TSliderBox.cxx:145
 TSliderBox.cxx:146
 TSliderBox.cxx:147
 TSliderBox.cxx:148
 TSliderBox.cxx:149
 TSliderBox.cxx:150
 TSliderBox.cxx:151
 TSliderBox.cxx:152
 TSliderBox.cxx:153
 TSliderBox.cxx:154
 TSliderBox.cxx:155
 TSliderBox.cxx:156
 TSliderBox.cxx:157
 TSliderBox.cxx:158
 TSliderBox.cxx:159
 TSliderBox.cxx:160
 TSliderBox.cxx:161
 TSliderBox.cxx:162
 TSliderBox.cxx:163
 TSliderBox.cxx:164
 TSliderBox.cxx:165
 TSliderBox.cxx:166
 TSliderBox.cxx:167
 TSliderBox.cxx:168
 TSliderBox.cxx:169
 TSliderBox.cxx:170
 TSliderBox.cxx:171
 TSliderBox.cxx:172
 TSliderBox.cxx:173
 TSliderBox.cxx:174
 TSliderBox.cxx:175
 TSliderBox.cxx:176
 TSliderBox.cxx:177
 TSliderBox.cxx:178
 TSliderBox.cxx:179
 TSliderBox.cxx:180
 TSliderBox.cxx:181
 TSliderBox.cxx:182
 TSliderBox.cxx:183
 TSliderBox.cxx:184
 TSliderBox.cxx:185
 TSliderBox.cxx:186
 TSliderBox.cxx:187
 TSliderBox.cxx:188
 TSliderBox.cxx:189
 TSliderBox.cxx:190
 TSliderBox.cxx:191
 TSliderBox.cxx:192
 TSliderBox.cxx:193
 TSliderBox.cxx:194
 TSliderBox.cxx:195
 TSliderBox.cxx:196
 TSliderBox.cxx:197
 TSliderBox.cxx:198
 TSliderBox.cxx:199
 TSliderBox.cxx:200
 TSliderBox.cxx:201
 TSliderBox.cxx:202
 TSliderBox.cxx:203
 TSliderBox.cxx:204
 TSliderBox.cxx:205
 TSliderBox.cxx:206
 TSliderBox.cxx:207
 TSliderBox.cxx:208
 TSliderBox.cxx:209
 TSliderBox.cxx:210
 TSliderBox.cxx:211
 TSliderBox.cxx:212
 TSliderBox.cxx:213
 TSliderBox.cxx:214
 TSliderBox.cxx:215
 TSliderBox.cxx:216
 TSliderBox.cxx:217
 TSliderBox.cxx:218
 TSliderBox.cxx:219
 TSliderBox.cxx:220
 TSliderBox.cxx:221
 TSliderBox.cxx:222
 TSliderBox.cxx:223
 TSliderBox.cxx:224
 TSliderBox.cxx:225
 TSliderBox.cxx:226
 TSliderBox.cxx:227
 TSliderBox.cxx:228
 TSliderBox.cxx:229
 TSliderBox.cxx:230
 TSliderBox.cxx:231
 TSliderBox.cxx:232
 TSliderBox.cxx:233
 TSliderBox.cxx:234
 TSliderBox.cxx:235
 TSliderBox.cxx:236
 TSliderBox.cxx:237
 TSliderBox.cxx:238
 TSliderBox.cxx:239
 TSliderBox.cxx:240
 TSliderBox.cxx:241
 TSliderBox.cxx:242
 TSliderBox.cxx:243
 TSliderBox.cxx:244
 TSliderBox.cxx:245
 TSliderBox.cxx:246
 TSliderBox.cxx:247
 TSliderBox.cxx:248
 TSliderBox.cxx:249
 TSliderBox.cxx:250
 TSliderBox.cxx:251
 TSliderBox.cxx:252
 TSliderBox.cxx:253
 TSliderBox.cxx:254
 TSliderBox.cxx:255
 TSliderBox.cxx:256
 TSliderBox.cxx:257
 TSliderBox.cxx:258
 TSliderBox.cxx:259
 TSliderBox.cxx:260
 TSliderBox.cxx:261
 TSliderBox.cxx:262
 TSliderBox.cxx:263
 TSliderBox.cxx:264
 TSliderBox.cxx:265
 TSliderBox.cxx:266
 TSliderBox.cxx:267
 TSliderBox.cxx:268
 TSliderBox.cxx:269
 TSliderBox.cxx:270
 TSliderBox.cxx:271
 TSliderBox.cxx:272
 TSliderBox.cxx:273
 TSliderBox.cxx:274
 TSliderBox.cxx:275
 TSliderBox.cxx:276
 TSliderBox.cxx:277
 TSliderBox.cxx:278
 TSliderBox.cxx:279
 TSliderBox.cxx:280
 TSliderBox.cxx:281
 TSliderBox.cxx:282
 TSliderBox.cxx:283
 TSliderBox.cxx:284
 TSliderBox.cxx:285
 TSliderBox.cxx:286
 TSliderBox.cxx:287
 TSliderBox.cxx:288
 TSliderBox.cxx:289
 TSliderBox.cxx:290
 TSliderBox.cxx:291
 TSliderBox.cxx:292
 TSliderBox.cxx:293
 TSliderBox.cxx:294
 TSliderBox.cxx:295
 TSliderBox.cxx:296