Subversion Repositories DIN Is Noise

Rev

Rev 2199 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1528 jag 1
/*
2
* slider.h
2302 jag 3
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
1528 jag 4
* For more information, please visit http://dinisnoise.org/
5
*/
6
 
7
 
8
#ifndef __slider
9
#define __slider
10
 
11
#include "widget.h"
12
#include "viewwin.h"
13
#include "utils.h"
14
#include "filled_button.h"
2199 jag 15
#include "input.h"
1528 jag 16
 
17
#include <algorithm>
18
#include <vector>
19
 
20
extern int mousex;
21
extern viewport view;
22
extern int lmb;
23
 
24
template <typename S> struct after_slide_lis {
25
  virtual void slided (S& s) = 0;
26
};
27
 
28
template <typename S> struct start_slide_lis {
29
  virtual void start_slide (S& s) = 0;
30
};
31
 
32
template <typename T> struct values {
33
 
34
  T low, high, delta, val;
35
  float amount;
36
 
37
  values (T l = 0, T h = 1, T v = 0) {
38
    set_limits (l, h);
39
    *this = v;
40
  }
41
 
42
  operator T() {
43
    return ((T) val);
44
  }
45
 
46
  void set_limits (T l, T h) {
47
    low = l;
48
    high = h;
49
    delta = high - low;
50
  }
51
 
52
  void get_limits (T& l, T& h) {
53
    l = low;
54
    h = high;
55
  }
56
 
57
  T operator() () const { return val; }
58
  values& operator= (const T& v) {
59
    val = v;
60
    clamp<T> (low, val, high);
61
    if (delta) amount = (val - low) * 1.0f / delta; else amount = 0;
62
    return *this;
63
  }
64
 
65
  void set_amount (float a) {
66
    amount = a;
67
    clamp<float> (0.0f, amount, 1.0f);
68
    val = (T) (low + delta * amount);
69
  }
70
 
71
  float get_amount () const { return amount; }
72
 
73
};
74
 
75
template <typename T> struct slider : widget, move_listener {
76
 
77
  values<T> vx;
78
  int dx;
2199 jag 79
  std::vector<int> dxa;
1528 jag 80
 
81
  int sliding;
82
  int lmb_clicked;
83
 
84
  change_listener<slider> *chgl;
85
  after_slide_lis<slider> *asl;
86
  start_slide_lis<slider> *ssl;
87
 
88
  filled_button sizer;
89
  static const int spc = 10;
90
 
91
  slider (int sv = 0, int w = 64, int h = 16) : widget (0, 0, w, h), vx (0, 0, 0), sliding(0), lmb_clicked(0) {
92
    chgl = 0;
93
    asl = 0;
94
    set_sizer_visible (sv);
95
  }
96
 
97
  void set_sizer_visible (int sv) {
98
    sizer.visible = sv;
99
    if (sizer.visible) {
100
      sizer.set_moveable (1);
101
      sizer.movlis = this;
102
    } else {
103
      sizer.set_moveable (0);
104
      sizer.movlis = 0;
105
    }
106
  }
107
 
108
  void set_pos (int x, int y) {
109
    widget::set_pos (x, y);
110
    sizer.set_pos (extents.right + spc, extents.bottom);
111
  }
112
 
113
  void set_right (int r) {
114
    set_extents (extents.left, extents.bottom, r, extents.top);
115
    dx = vx.get_amount () * extents.width;
116
  }
117
 
2064 jag 118
  void set_size (int w) {
119
    set_extents (extents.left, extents.bottom, extents.left + w, extents.top);
120
    dx = vx.get_amount () * extents.width;
121
  }
122
 
1528 jag 123
  void moved () {
124
    int mpx = mousex - movr.prevx;
125
    if (mpx) {
126
      sizer.set_pos (mousex, extents.bottom);
127
      int msx = mousex - spc;
128
      if (msx > extents.left) set_right (msx);
129
    }
130
  }
131
 
132
  int handle_input () {
133
 
134
    widget::handle_input ();
135
 
136
    if (sizer.visible && sizer.handle_input ()) return 1;
137
 
138
    int ret = 0;
139
 
140
    if (lmb) {
141
      if (lmb_clicked == 0) {
142
        if (sliding) {
143
          sliding = 0;
144
          if (asl) asl->slided (*this);
145
          defocus (this);
146
          ret = 1;
147
        } else {
148
          if (hover) {
149
            sliding = 1;
150
            if (ssl) ssl->start_slide (*this);
151
            widget::focus = this;
152
            ret = 1;
153
          }
154
        }
155
        lmb_clicked = 1;
156
      }
157
    } else {
158
      if (sliding) {
159
        int nu_dx = mousex - extents.left;
160
        clamp (0, nu_dx, extents.width);
161
        if (nu_dx != dx) {
162
          dx = nu_dx;
163
          vx.set_amount (dx * extents.width_1);
164
          if (chgl) chgl->changed (*this);
165
        }
2199 jag 166
        if (keypressed(SDLK_f)) dxa.push_back (dx);
167
        if (keypressed(SDLK_BACKSPACE)) dxa.clear ();
2064 jag 168
      } else
169
        ret = 0;
1528 jag 170
      lmb_clicked = 0;
171
    }
2199 jag 172
 
173
 
1528 jag 174
    return ret;
175
 
176
  }
177
 
178
  void draw () {
179
 
180
    widget::draw ();
181
 
182
    glEnable (GL_BLEND);
183
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
184
 
185
    const color& c = clr;
186
 
2064 jag 187
    glColor4f (c.r, c.g, c.b, (GLfloat) 0.25);
1528 jag 188
 
189
    const box<int>& e = extents;
190
      glRecti (e.left, e.bottom, e.right, e.top);
191
 
2064 jag 192
    glColor4f (c.r, c.g, c.b, GLfloat (1));
1528 jag 193
      glRecti (e.left, e.bottom, e.left + dx, e.top);
194
 
195
    glDisable (GL_BLEND);
196
 
2199 jag 197
    glColor3f (1, 1, 1);
198
    for (int i = 0, j = dxa.size (); i < j; ++i) {
199
      int dxi = extents.left + dxa[i];
200
      glBegin (GL_LINES);
201
        glVertex2i (dxi, extents.top + spc);
202
        glVertex2i (dxi, extents.bottom - spc);
203
      glEnd ();
204
    }
205
 
1528 jag 206
    if (sizer.visible) sizer.draw ();
207
 
208
  }
209
 
210
  void update () {
211
    float amount = vx.get_amount ();
212
    const box<int>& e = extents;
213
    dx = (int) (amount * e.width);  
214
  }
215
 
216
  void set_listener (change_listener<slider>* _chgl, start_slide_lis<slider>* _ssl = 0, after_slide_lis<slider>* _asl = 0) {
217
    chgl = _chgl;
218
    ssl = _ssl;
219
    asl = _asl;
220
  }
221
 
222
  T operator() () const {return vx (); }
223
 
224
  void set_val (const T& t) {
225
    vx = t;
226
    update ();
227
  }
228
 
229
  void set_limits (T l, T h) {
230
    vx = values<T> (l, h, vx());
231
    update ();
232
  }
233
 
234
  void get_limits (T& l, T& h) {
235
    vx.get_limits (l, h);
236
  }
237
};
238
 
239
#define MAKE_SLIDER_LISTENER(name,var) struct name : change_listener< slider<float> > { void changed (slider<float>& s); }; name var;
240
#define SLIDER_CHANGED(scope,name) void scope::name::changed (slider<float>& s)
241
#define MAKE_AFTER_SLIDE_LISTENER(name,type,var) struct name : after_slide_lis< type > { void slided (type& s); }; name var;
242
#define SLIDED(scope,name,type) void scope::name::slided (type& s)
243
#define MAKE_START_SLIDE_LISTENER(name,type,var) struct name : start_slide_lis< type > { void start_slide (type& s); }; name var;
244
#define START_SLIDE(scope,name,type) void scope::name::start_slide (type& s)
245
 
246
#endif