Flu_Dual_Slider.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. // $Id: Flu_Dual_Slider.cpp,v 1.2 2004/06/11 13:02:56 jbryan Exp $
  2. /***************************************************************
  3. * FLU - FLTK Utility Widgets
  4. * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University
  5. *
  6. * This file and its content is protected by a software license.
  7. * You should have received a copy of this license with this file.
  8. * If not, please contact the Ohio Supercomputer Center immediately:
  9. * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212
  10. *
  11. ***************************************************************/
  12. #include "FLU/Flu_Dual_Slider.H"
  13. Flu_Dual_Slider :: Flu_Dual_Slider( int x, int y, int w, int h, const char *l )
  14. : Fl_Valuator( x, y, w, h, l )
  15. {
  16. _grab = 0;
  17. _overlap = false;
  18. _lFocus = true;
  19. _lVal = lowValue = 0.0f;
  20. _hVal = highValue = 1.0f;
  21. _lGrabbed = _hGrabbed = false;
  22. precision(2);
  23. box( FL_DOWN_BOX );
  24. }
  25. Flu_Dual_Slider :: ~Flu_Dual_Slider()
  26. {
  27. }
  28. int Flu_Dual_Slider :: handle( int event )
  29. {
  30. switch( event )
  31. {
  32. case FL_PUSH:
  33. if( Fl::visible_focus() ) Fl::focus(this);
  34. if( Fl::event_inside( _lHandle[0], _lHandle[1], _lHandle[2], _lHandle[3] ) )
  35. {
  36. set_value( lowValue );
  37. handle_push();
  38. _lGrabbed = true;
  39. _lFocus = true;
  40. _grabDelta = _horizontal() ?
  41. Fl::event_x()-_lHandle[0] :
  42. Fl::event_y()-_lHandle[1];
  43. redraw();
  44. return 1;
  45. }
  46. else if( Fl::event_inside( _hHandle[0], _hHandle[1], _hHandle[2], _hHandle[3] ) )
  47. {
  48. set_value( highValue );
  49. handle_push();
  50. _hGrabbed = true;
  51. _lFocus = false;
  52. _grabDelta = _horizontal() ?
  53. Fl::event_x()-_hHandle[0] :
  54. Fl::event_y()-_hHandle[1];
  55. redraw();
  56. return 1;
  57. }
  58. break;
  59. case FL_DRAG:
  60. {
  61. float min = minimum(), max = maximum();
  62. bool flip = false;
  63. if( min > max )
  64. {
  65. min = maximum();
  66. max = minimum();
  67. flip = true;
  68. range( min, max );
  69. }
  70. //int X = x()+Fl::box_dx(box()), Y = y()+Fl::box_dy(box()),
  71. int W = w()-Fl::box_dw(box()), H = h()-Fl::box_dh(box());
  72. int s = _horizontal() ? H/2 : W/2;
  73. int S = _horizontal() ? W : H;
  74. if( _nice() )
  75. s += 4;
  76. if( _lGrabbed )
  77. {
  78. int diff = _horizontal() ?
  79. (Fl::event_x() - _grabDelta) - x() :
  80. (Fl::event_y() - _grabDelta) - y();
  81. _lVal = float(diff)/float(S-s-s);
  82. if( _lVal < 0.0f ) _lVal = 0.0f;
  83. if( _lVal >= _hVal ) _lVal = _hVal;
  84. redraw();
  85. lowValue = min + _lVal*(max-min);
  86. lowValue = round(lowValue);
  87. if( lowValue >= highValue )
  88. lowValue = _overlap ? highValue : clamp( increment( highValue, -1 ) );
  89. lowValue = clamp(lowValue);
  90. if( flip )
  91. range( max, min );
  92. handle_drag( lowValue );
  93. }
  94. else if( _hGrabbed )
  95. {
  96. int diff = _horizontal() ?
  97. (Fl::event_x() - _grabDelta - s) - x() :
  98. (Fl::event_y() - _grabDelta - s) - y();
  99. _hVal = float(diff)/float(S-s-s);
  100. if( _hVal <= _lVal ) _hVal = _lVal;
  101. if( _hVal > 1.0f ) _hVal = 1.0f;
  102. redraw();
  103. highValue = min + _hVal*(max-min);
  104. highValue = round(highValue);
  105. if( highValue <= lowValue )
  106. highValue = _overlap ? lowValue : clamp( increment( lowValue, 1 ) );
  107. highValue = clamp(highValue);
  108. if( flip )
  109. range( max, min );
  110. handle_drag( highValue );
  111. }
  112. }
  113. break;
  114. case FL_RELEASE:
  115. _lGrabbed = _hGrabbed = false;
  116. handle_release();
  117. break;
  118. case FL_KEYBOARD:
  119. switch( Fl::event_key() )
  120. {
  121. case FL_Up:
  122. if( _horizontal() )
  123. _lFocus = !_lFocus;
  124. else
  125. {
  126. int inc = minimum() > maximum() ? 1 : -1;
  127. if( _lFocus )
  128. {
  129. set_value( lowValue );
  130. lowValue = clamp( increment( lowValue, inc ) );
  131. if( lowValue >= highValue )
  132. lowValue = _overlap ? highValue : clamp( increment( highValue, inc ) );
  133. handle_drag( lowValue );
  134. handle_release();
  135. }
  136. else
  137. {
  138. set_value( highValue );
  139. highValue = clamp( increment( highValue, inc ) );
  140. if( highValue <= lowValue )
  141. highValue = _overlap ? lowValue : clamp( increment( lowValue, -inc ) );
  142. handle_drag( highValue );
  143. handle_release();
  144. }
  145. }
  146. redraw();
  147. return 1;
  148. case FL_Down:
  149. if( _horizontal() )
  150. _lFocus = !_lFocus;
  151. else
  152. {
  153. int inc = minimum() > maximum() ? -1 : 1;
  154. if( _lFocus )
  155. {
  156. set_value( lowValue );
  157. lowValue = clamp( increment( lowValue, inc ) );
  158. if( lowValue >= highValue )
  159. lowValue = _overlap ? highValue : clamp( increment( highValue, -inc ) );
  160. handle_drag( lowValue );
  161. handle_release();
  162. }
  163. else
  164. {
  165. set_value( highValue );
  166. highValue = clamp( increment( highValue, inc ) );
  167. if( highValue <= lowValue )
  168. highValue = _overlap ? lowValue : clamp( increment( lowValue, inc ) );
  169. handle_drag( highValue );
  170. handle_release();
  171. }
  172. }
  173. redraw();
  174. return 1;
  175. case FL_Left:
  176. if( _horizontal() )
  177. {
  178. int inc = minimum() > maximum() ? 1 : -1;
  179. if( _lFocus )
  180. {
  181. set_value( lowValue );
  182. lowValue = clamp( increment( lowValue, inc ) );
  183. if( lowValue >= highValue )
  184. lowValue = _overlap ? highValue : clamp( increment( highValue, inc ) );
  185. handle_drag( lowValue );
  186. handle_release();
  187. }
  188. else
  189. {
  190. set_value( highValue );
  191. highValue = clamp( increment( highValue, inc ) );
  192. if( highValue <= lowValue )
  193. highValue = _overlap ? lowValue : clamp( increment( lowValue, -inc ) );
  194. handle_drag( highValue );
  195. handle_release();
  196. }
  197. }
  198. else
  199. _lFocus = !_lFocus;
  200. redraw();
  201. return 1;
  202. case FL_Right:
  203. if( _horizontal() )
  204. {
  205. int inc = minimum() > maximum() ? -1 : 1;
  206. if( _lFocus )
  207. {
  208. set_value( lowValue );
  209. lowValue = clamp( increment( lowValue, inc ) );
  210. if( lowValue >= highValue )
  211. lowValue = _overlap ? highValue : clamp( increment( highValue, -inc ) );
  212. handle_drag( lowValue );
  213. handle_release();
  214. }
  215. else
  216. {
  217. set_value( highValue );
  218. highValue = clamp( increment( highValue, inc ) );
  219. if( highValue <= lowValue )
  220. highValue = _overlap ? lowValue : clamp( increment( lowValue, inc ) );
  221. handle_drag( highValue );
  222. handle_release();
  223. }
  224. }
  225. else
  226. _lFocus = !_lFocus;
  227. redraw();
  228. return 1;
  229. }
  230. break;
  231. case FL_FOCUS:
  232. case FL_UNFOCUS:
  233. if( Fl::visible_focus() )
  234. {
  235. redraw();
  236. return 1;
  237. }
  238. else
  239. return 0;
  240. case FL_ENTER :
  241. case FL_LEAVE :
  242. return 1;
  243. }
  244. return Fl_Valuator::handle(event);
  245. }
  246. void Flu_Dual_Slider :: draw()
  247. {
  248. float min = minimum(), max = maximum();
  249. if( min > max )
  250. {
  251. min = maximum();
  252. max = minimum();
  253. }
  254. float lo = (lowValue - min)/(max-min),
  255. hi = (highValue - min)/(max-min);
  256. draw_box();
  257. int X = x()+Fl::box_dx(box()), Y = y()+Fl::box_dy(box()),
  258. W = w()-Fl::box_dw(box()), H = h()-Fl::box_dh(box());
  259. int s = _horizontal() ? h()/2 : w()/2;
  260. int S = _horizontal() ? W : H;
  261. if( _nice() )
  262. s += 4;
  263. int loOff = _horizontal() ?
  264. X + int(lo*float(S-s-s)) :
  265. Y + int(lo*float(S-s-s));
  266. int hiOff = _horizontal() ?
  267. X + s + int(hi*float(S-s-s)) :
  268. Y + s + int(hi*float(S-s-s));
  269. if( _nice() )
  270. {
  271. Fl_Color black = active_r() ? FL_FOREGROUND_COLOR : FL_INACTIVE_COLOR;
  272. if( _horizontal() )
  273. draw_box( FL_THIN_DOWN_BOX, X+2, Y+H/2-2, W-4, 4, black );
  274. else
  275. draw_box( FL_THIN_DOWN_BOX, X+W/2-2, Y+2, 4, H-4, black );
  276. }
  277. if( _horizontal() )
  278. {
  279. _lHandle[0] = loOff; _lHandle[1] = Y; _lHandle[2] = s; _lHandle[3] = H;
  280. _hHandle[0] = hiOff; _hHandle[1] = Y; _hHandle[2] = s; _hHandle[3] = H;
  281. draw_box( FL_UP_BOX, loOff, Y, s, H, FL_GRAY);
  282. draw_box( FL_UP_BOX, hiOff, Y, s, H, FL_GRAY);
  283. if( _nice() )
  284. {
  285. draw_box( FL_THIN_DOWN_BOX, loOff+s/2-3, Y+2, 6, H-4, FL_GRAY);
  286. draw_box( FL_THIN_DOWN_BOX, hiOff+s/2-3, Y+2, 6, H-4, FL_GRAY);
  287. }
  288. }
  289. else
  290. {
  291. _lHandle[0] = X; _lHandle[1] = loOff; _lHandle[2] = W; _lHandle[3] = s;
  292. _hHandle[0] = X; _hHandle[1] = hiOff; _hHandle[2] = W; _hHandle[3] = s;
  293. draw_box( FL_UP_BOX, X, loOff, W, s, FL_GRAY);
  294. draw_box( FL_UP_BOX, X, hiOff, W, s, FL_GRAY);
  295. if( _nice() )
  296. {
  297. draw_box( FL_THIN_DOWN_BOX, X+2, loOff+s/2-3, W-4, 6, FL_GRAY);
  298. draw_box( FL_THIN_DOWN_BOX, X+2, hiOff+s/2-3, W-4, 6, FL_GRAY);
  299. }
  300. }
  301. if( Fl::focus() == this )
  302. {
  303. if( _lFocus )
  304. {
  305. if( _horizontal() )
  306. draw_focus( FL_UP_BOX, loOff, Y, s, H );
  307. else
  308. draw_focus( FL_UP_BOX, X, loOff, W, s );
  309. }
  310. else
  311. {
  312. if( _horizontal() )
  313. draw_focus( FL_UP_BOX, hiOff, Y, s, H );
  314. else
  315. draw_focus( FL_UP_BOX, X, hiOff, W, s );
  316. }
  317. }
  318. }