/clxclient-3.6.1/slider.cc

# · C++ · 356 lines · 272 code · 65 blank · 19 comment · 43 complexity · 26fdc3b0662da0aa867c187ffe5c03e7 MD5 · raw file

  1. // ---------------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU Lesser General Public License as published
  7. // by the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU Lesser General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU Lesser General Public
  16. // License along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. //
  19. // ---------------------------------------------------------------------------------
  20. #include "clxclient.h"
  21. X_slider::X_slider (X_window *parent, X_callback *callb, X_slider_style *style, X_scale_style *scale,
  22. int xp, int yp, int xs, int ys, int cbid) :
  23. X_window (parent, xp, yp, xs, ys, style->bg),
  24. _callb (callb),
  25. _style (style),
  26. _scale (scale),
  27. _x (0),
  28. _y (0),
  29. _i (_scale->pix [0]),
  30. _d (9999),
  31. _cbid (cbid),
  32. _knob (_style->knob),
  33. _mark (_style->mark)
  34. {
  35. x_add_events (ExposureMask | Button1MotionMask | ButtonPressMask | ButtonReleaseMask);
  36. }
  37. void X_slider::brelease (XButtonEvent *E)
  38. {
  39. _d = 9999;
  40. if (_callb) _callb->handle_callb (X_callback::SLIDER | STOP, this, (XEvent *) E);
  41. }
  42. X_hslider::X_hslider (X_window *parent, X_callback *callb, X_slider_style *style, X_scale_style *scale,
  43. int xp, int yp, int h, int cbid) :
  44. X_slider (parent, callb, style, scale, xp, yp, scale->length (), h, cbid)
  45. {
  46. _y = h;
  47. _x = _scale->marg;
  48. }
  49. void X_hslider::handle_event (XEvent *E)
  50. {
  51. XMotionEvent *M = (XMotionEvent *) E;
  52. XButtonEvent *B = (XButtonEvent *) E;
  53. switch (E->type)
  54. {
  55. case Expose:
  56. plines ();
  57. plknob (_i);
  58. break;
  59. case ButtonPress:
  60. if (B->button == Button4)
  61. {
  62. if (domove (_scale->limit (_i + 1)) && _callb)
  63. {
  64. _callb->handle_callb (X_callback::SLIDER | MOVE, this, (XEvent *) E);
  65. }
  66. }
  67. else if (B->button == Button5)
  68. {
  69. if (domove (_scale->limit (_i - 1)) && _callb)
  70. {
  71. _callb->handle_callb (X_callback::SLIDER | MOVE, this, (XEvent *) E);
  72. }
  73. }
  74. else
  75. {
  76. _d = B->x - _x - _i;
  77. if (abs (2 * _d) >= _style->h) _d = 9999;
  78. }
  79. break;
  80. case ButtonRelease:
  81. brelease (B);
  82. break;
  83. case MotionNotify:
  84. if ((_d < 9999) && domove (_scale->limit (M->x - _x - _d)) && _callb)
  85. {
  86. _callb->handle_callb (X_callback::SLIDER | MOVE, this, (XEvent *) E);
  87. }
  88. break;
  89. default:
  90. fprintf (stderr, "X_slider: event %d\n", E->type );
  91. }
  92. }
  93. void X_hslider::set_color (unsigned long knob, unsigned long mark)
  94. {
  95. if ((_knob != knob) || (_mark != mark))
  96. {
  97. _knob = knob;
  98. _mark = mark;
  99. plknob (_i);
  100. }
  101. }
  102. void X_hslider::set_val (float v)
  103. {
  104. domove (_scale->calcpix (v));
  105. }
  106. bool X_hslider::domove (int i)
  107. {
  108. if (i == _i) return false;
  109. erase (_i);
  110. plines ();
  111. plknob (_i = i);
  112. return true;
  113. }
  114. void X_hslider::plines (void)
  115. {
  116. int x, k, *p;
  117. GC gc = disp ()->dgc ();
  118. XSetFunction (dpy (), gc, GXcopy);
  119. XSetLineAttributes (dpy (), gc, 1, LineSolid, CapButt, JoinBevel);
  120. XSetForeground (dpy (), gc, _scale->fg->pixel);
  121. k = _scale->nseg + 1;
  122. p = _scale->pix;
  123. while (k--)
  124. {
  125. x = _x + *p++;
  126. XDrawLine (dpy (), win (), gc, x, 0, x, _y);
  127. }
  128. k = _y / 2;
  129. XSetForeground (dpy (), gc, _style->dark);
  130. XDrawLine (dpy (), win (), gc, _x, k - 1, _x + _scale->pixlen (), k - 1);
  131. XSetForeground (dpy (), gc, _style->lite);
  132. XDrawLine (dpy (), win (), gc, _x, k, _x + _scale->pixlen (), k);
  133. }
  134. void X_hslider::plknob (int i)
  135. {
  136. int x, y, h, w;
  137. GC gc = disp ()->dgc ();
  138. h = _style->h;
  139. w = _style->w;
  140. x = i + _x - h / 2;
  141. y = (_y - w) / 2;
  142. XSetFunction (dpy (), gc, GXcopy);
  143. XSetLineAttributes (dpy (), gc, 1, LineSolid, CapButt, JoinBevel);
  144. XSetForeground (dpy (), gc, _knob);
  145. XFillRectangle (dpy (), win (), gc, x, y, h, w);
  146. XSetForeground (dpy (), gc, _mark);
  147. XDrawLine (dpy (), win (), gc, x + h / 2, y, x + h / 2, y + w);
  148. XSetForeground (dpy (), gc, _style->lite);
  149. XDrawLine (dpy (), win (), gc, x - 1, y - 1, x - 1, y + w);
  150. XDrawLine (dpy (), win (), gc, x - 1, y - 1, x + h, y - 1);
  151. XSetForeground (dpy (), gc, _style->dark);
  152. XDrawLine (dpy (), win (), gc, x + h, y + w, x + h, y);
  153. XDrawLine (dpy (), win (), gc, x + h, y + w, x, y + w);
  154. }
  155. void X_hslider::erase (int i)
  156. {
  157. int x, y, h, w;
  158. GC gc = disp ()->dgc ();
  159. h = _style->h;
  160. w = _style->w;
  161. x = i + _x - h / 2;
  162. y = (_y - w) / 2;
  163. XSetFunction (dpy (), gc, GXcopy);
  164. XSetForeground (dpy (), gc, _style->bg);
  165. XFillRectangle (dpy (), win (), gc, x - 1, y - 1, h + 2, w + 2);
  166. }
  167. X_vslider::X_vslider (X_window *parent, X_callback *callb, X_slider_style *style, X_scale_style *scale,
  168. int xp, int yp, int w, int cbid) :
  169. X_slider (parent, callb, style, scale, xp, yp, w, scale->length (), cbid)
  170. {
  171. _x = w;
  172. _y = _scale->marg + scale->pixlen () - 1;
  173. }
  174. void X_vslider::handle_event (XEvent *E)
  175. {
  176. XMotionEvent *M = (XMotionEvent *) E;
  177. XButtonEvent *B = (XButtonEvent *) E;
  178. switch (E->type)
  179. {
  180. case Expose:
  181. plines ();
  182. plknob (_i);
  183. break;
  184. case ButtonPress:
  185. if (B->button == Button4)
  186. {
  187. if (domove (_scale->limit (_i + 1)) && _callb)
  188. {
  189. _callb->handle_callb (X_callback::SLIDER | MOVE, this, (XEvent *) E);
  190. }
  191. }
  192. else if (B->button == Button5)
  193. {
  194. if (domove (_scale->limit (_i - 1)) && _callb)
  195. {
  196. _callb->handle_callb (X_callback::SLIDER | MOVE, this, (XEvent *) E);
  197. }
  198. }
  199. else
  200. {
  201. _d = M->y - _y + _i;
  202. if (abs (2 * _d) >= _style->h) _d = 9999;
  203. }
  204. break;
  205. case ButtonRelease:
  206. brelease (B);
  207. break;
  208. case MotionNotify:
  209. if ((_d < 9999) && domove (_scale->limit (_d + _y - M->y)) && _callb)
  210. {
  211. _callb->handle_callb (X_callback::SLIDER | MOVE, this, (XEvent *) E);
  212. }
  213. break;
  214. default:
  215. fprintf (stderr, "X_slider: event %d\n", E->type );
  216. }
  217. }
  218. void X_vslider::set_color (unsigned long knob, unsigned long mark)
  219. {
  220. if ((_knob != knob) || (_mark != mark))
  221. {
  222. _knob = knob;
  223. _mark = mark;
  224. plknob (_i);
  225. }
  226. }
  227. void X_vslider::set_val (float v)
  228. {
  229. domove (_scale->calcpix (v));
  230. }
  231. bool X_vslider::domove (int i)
  232. {
  233. if (i == _i) return false;
  234. erase (_i);
  235. plines ();
  236. plknob (_i = i);
  237. return true;
  238. }
  239. void X_vslider::plines (void)
  240. {
  241. int k, y, *p;
  242. GC gc = disp ()->dgc ();
  243. XSetFunction (dpy (), gc, GXcopy);
  244. XSetLineAttributes (dpy (), gc, 1, LineSolid, CapButt, JoinBevel);
  245. XSetForeground (dpy (), gc, _scale->fg->pixel);
  246. k = _scale->nseg + 1;
  247. p = _scale->pix;
  248. while (k--)
  249. {
  250. y = _y - *p++;
  251. XDrawLine (dpy (), win (), gc, 0, y, _x, y);
  252. }
  253. k = _x / 2;
  254. XSetForeground (dpy (), gc, _style->dark);
  255. XDrawLine (dpy (), win (), gc, k - 1, _y - _scale->pixlen (), k - 1, _y);
  256. XSetForeground (dpy (), gc, _style->lite);
  257. XDrawLine (dpy (), win (), gc, k, _y - _scale->pixlen (), k, _y);
  258. }
  259. void X_vslider::plknob (int i)
  260. {
  261. int x, y, h, w;
  262. GC gc = disp ()->dgc ();
  263. h = _style->h;
  264. w = _style->w;
  265. x = (_x - w) / 2;
  266. y = _y - i - h / 2;
  267. XSetFunction (dpy (), gc, GXcopy);
  268. XSetLineAttributes (dpy (), gc, 1, LineSolid, CapButt, JoinBevel);
  269. XSetForeground (dpy (), gc, _knob);
  270. XFillRectangle (dpy (), win (), gc, x, y, w, h);
  271. XSetForeground (dpy (), gc, _mark);
  272. XDrawLine (dpy (), win (), gc, x, y + h / 2, x + w, y + h / 2);
  273. XSetForeground (dpy (), gc, _style->lite);
  274. XDrawLine (dpy (), win (), gc, x - 1, y - 1, x - 1, y + h);
  275. XDrawLine (dpy (), win (), gc, x - 1, y - 1, x + w, y - 1);
  276. XSetForeground (dpy (), gc, _style->dark);
  277. XDrawLine (dpy (), win (), gc, x + w, y + h, x, y + h);
  278. XDrawLine (dpy (), win (), gc, x + w, y + h, x + w, y);
  279. }
  280. void X_vslider::erase (int i)
  281. {
  282. int x, y, h, w;
  283. GC gc = disp ()->dgc ();
  284. h = _style->h;
  285. w = _style->w;
  286. x = (_x - w) / 2;
  287. y = _y - i - h / 2;
  288. XSetFunction (dpy (), gc, GXcopy);
  289. XSetForeground (dpy (), gc, _style->bg);
  290. XFillRectangle (dpy (), win (), gc, x - 1, y - 1, w + 2, h + 2);
  291. }