You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

338 lines
7.3KB

  1. // generated by Fast Light User Interface Designer (fluid) version 1.0100
  2. #include "Fl_Knob.H"
  3. #include <Fl/fl_draw.H>
  4. #include <math.h>
  5. Fl_Knob::Fl_Knob(int xx,int yy,int ww,int hh,const char *l): Fl_Valuator(xx,yy,ww,hh,l) {
  6. int side;
  7. a1 = 35;
  8. a2 = 325;
  9. _type = DOTLIN;
  10. _percent = 0.3;
  11. _scaleticks = 10;
  12. _capr = _capg = _capb = -1;
  13. side = ww > hh ? hh:ww;
  14. _capsize = 100*(float)(side - 10) / (float)side;
  15. }
  16. Fl_Knob::~Fl_Knob() {
  17. }
  18. void Fl_Knob::draw() {
  19. int ox,oy,ww,hh,side;
  20. int capradius;
  21. int capoffset;
  22. float sa,ca,a_r;
  23. unsigned char rr,gg,bb;
  24. ox = x();
  25. oy = y();
  26. ww = w();
  27. hh = h();
  28. draw_label();
  29. fl_clip(ox,oy,ww,hh);
  30. if (ww > hh)
  31. {
  32. side = hh;
  33. ox = ox + (ww - side) / 2;
  34. }
  35. else
  36. {
  37. side = ww;
  38. oy = oy + (hh - side) / 2;
  39. }
  40. side = ww > hh ? hh:ww;
  41. int dam = damage();
  42. capradius = (int)((side-11) * (_capsize / 100.0));
  43. capoffset = (side - capradius)/2;
  44. if (dam & FL_DAMAGE_ALL)
  45. {
  46. int col = ((Fl_Widget *)parent())->color();
  47. // Clear rectangle with parent color
  48. fl_color(col);
  49. fl_rectf(ox,oy,side,side);
  50. // Cast round shadow
  51. Fl::get_color((Fl_Color)col,rr,gg,bb);
  52. shadow(-60,rr,gg,bb);
  53. fl_pie(ox+9,oy+9,side-12,side-12,0,360);
  54. // Draw ticks
  55. draw_scale(ox,oy,side);
  56. col = color();
  57. Fl::get_color((Fl_Color)col,rr,gg,bb);
  58. // Draw hilights of the button crown
  59. shadow(7,rr,gg,bb);
  60. fl_pie(ox+6,oy+6,side-12,side-12,40,50);
  61. fl_pie(ox+6,oy+6,side-12,side-12,260,270);
  62. shadow(15,rr,gg,bb);
  63. fl_pie(ox+6,oy+6,side-12,side-12,50,70);
  64. fl_pie(ox+6,oy+6,side-12,side-12,230,260);
  65. shadow(25,rr,gg,bb);
  66. fl_pie(ox+6,oy+6,side-12,side-12,70,80);
  67. fl_pie(ox+6,oy+6,side-12,side-12,220,230);
  68. shadow(30,rr,gg,bb);
  69. fl_pie(ox+6,oy+6,side-12,side-12,80,220);
  70. shadow(-9,rr,gg,bb);
  71. fl_pie(ox+6,oy+6,side-12,side-12,30,40);
  72. fl_pie(ox+6,oy+6,side-12,side-12,270,280);
  73. shadow(-18,rr,gg,bb);
  74. fl_pie(ox+6,oy+6,side-12,side-12,280,400);
  75. shadow(-28,rr,gg,bb);
  76. fl_pie(ox+6,oy+6,side-12,side-12,290,390);
  77. fl_color(FL_BLACK);
  78. fl_arc(ox+6,oy+6,side-11,side-11,0,360);
  79. }
  80. Fl::get_color((Fl_Color)color(),rr,gg,bb);
  81. // Draw button cap
  82. if (_capr != -1)
  83. { rr = _capr; gg = _capg; bb = _capb;}
  84. else
  85. Fl::get_color((Fl_Color)color(),rr,gg,bb);
  86. fl_color(rr,gg,bb);
  87. int xx = ox + capoffset;
  88. int yy = oy + capoffset;
  89. int dx = capradius;
  90. fl_pie(xx,yy,dx,dx,0,360);
  91. // Draw hilights of button cap
  92. shadow(10,rr,gg,bb);
  93. fl_pie(xx,yy,dx,dx,110,150);
  94. fl_pie(xx,yy,dx,dx,290,330);
  95. shadow(17,rr,gg,bb);
  96. fl_pie(xx,yy,dx,dx,120,140);
  97. fl_pie(xx,yy,dx,dx,300,320);
  98. shadow(30,rr,gg,bb);
  99. fl_pie(xx,yy,dx,dx,127,133);
  100. fl_pie(xx,yy,dx,dx,307,313);
  101. shadow(-7,rr,gg,bb);
  102. fl_pie(xx,yy,dx,dx,50,90);
  103. fl_pie(xx,yy,dx,dx,230,290);
  104. shadow(-15,rr,gg,bb);
  105. fl_pie(xx,yy,dx,dx,65,75);
  106. fl_pie(xx,yy,dx,dx,242,278);
  107. // Draw the button cursor
  108. draw_cursor(ox+side/2,oy+side/2,dx/2);
  109. fl_pop_clip();
  110. }
  111. int Fl_Knob::handle(int event) {
  112. int ox,oy,ww,hh;
  113. ox = x() + 10; oy = y() + 10;
  114. ww = w() - 20;
  115. hh = h()-20;
  116. switch (event)
  117. {
  118. case FL_PUSH:
  119. handle_push();
  120. case FL_DRAG:
  121. {
  122. int mx = Fl::event_x()-ox-ww/2;
  123. int my = Fl::event_y()-oy-hh/2;
  124. if (!mx && !my) return 1;
  125. double angle = 270-atan2((float)-my, (float)mx)*180/M_PI;
  126. double oldangle = (a2-a1)*(value()-minimum())/(maximum()-minimum()) + a1;
  127. while (angle < oldangle-180) angle += 360;
  128. while (angle > oldangle+180) angle -= 360;
  129. double val;
  130. if ((a1<a2) ? (angle <= a1) : (angle >= a1))
  131. {
  132. val = minimum();
  133. }
  134. else
  135. if ((a1<a2) ? (angle >= a2) : (angle <= a2))
  136. {
  137. val = maximum();
  138. }
  139. else
  140. {
  141. val = minimum() + (maximum()-minimum())*(angle-a1)/(a2-a1);
  142. }
  143. handle_drag(clamp(round(val)));
  144. }
  145. return 1;
  146. case FL_RELEASE:
  147. handle_release();
  148. return 1;
  149. default:
  150. return 0;
  151. }
  152. return 0;
  153. }
  154. void Fl_Knob::shadow(const int offs,const uchar r,uchar g,uchar b) {
  155. int rr,gg,bb;
  156. rr = r + offs;
  157. rr = rr > 255 ? 255:rr;
  158. rr = rr < 0 ? 0:rr;
  159. gg = g + offs;
  160. gg = gg > 255 ? 255:gg;
  161. gg = gg < 0 ? 0:gg;
  162. bb = b + offs;
  163. bb = bb > 255 ? 255:bb;
  164. bb = bb < 0 ? 0:bb;
  165. fl_color((uchar)rr,(uchar)gg,(uchar)bb);
  166. }
  167. void Fl_Knob::draw_scale(const int ox,const int oy,const int side) {
  168. float x1,y1,x2,y2,rds,cx,cy,ca,sa;
  169. float minv,maxv,curv;
  170. rds = side / 2;
  171. cx = ox + side / 2;
  172. cy = oy + side / 2;
  173. if (!(_type & DOTLOG_3))
  174. {
  175. if (_scaleticks == 0) return;
  176. double a_step = (10.0*3.14159/6.0) / _scaleticks;
  177. double a_orig = -(3.14159/3.0);
  178. for (int a = 0; a <= _scaleticks; a++)
  179. {
  180. double na = a_orig + a * a_step;
  181. ca = cos(na);
  182. sa = sin(na);
  183. x1 = cx + rds * ca;
  184. y1 = cy - rds * sa;
  185. x2 = cx + (rds-6) * ca;
  186. y2 = cy - (rds-6) * sa;
  187. fl_color(FL_BLACK);
  188. fl_line((int)x1,(int)y1,(int)x2,(int)y2);
  189. fl_color(FL_WHITE);
  190. if (sa*ca >=0)
  191. fl_line((int)x1+1,(int)y1+1,(int)x2+1,(int)y2+1);
  192. else
  193. fl_line((int)x1+1,(int)y1-1,(int)x2+1,(int)y2-1);
  194. }
  195. }
  196. else
  197. {
  198. int nb_dec = (_type & DOTLOG_3);
  199. for (int k = 0; k < nb_dec; k++)
  200. {
  201. double a_step = (10.0*3.14159/6.0) / nb_dec;
  202. double a_orig = -(3.14159/3.0) + k * a_step;
  203. for (int a = (k) ? 2:1; a <= 10; )
  204. {
  205. double na = a_orig + log10((double)a) * a_step;
  206. ca = cos(na);
  207. sa = sin(na);
  208. x1 = cx - rds * ca;
  209. y1 = cy - rds * sa;
  210. x2 = cx - (rds-6) * ca;
  211. y2 = cy - (rds-6) * sa;
  212. fl_color(FL_BLACK);
  213. fl_line((int)x1,(int)y1,(int)x2,(int)y2);
  214. fl_color(FL_WHITE);
  215. if (sa*ca <0)
  216. fl_line((int)x1+1,(int)y1+1,(int)x2+1,(int)y2+1);
  217. else
  218. fl_line((int)x1+1,(int)y1-1,(int)x2+1,(int)y2-1);
  219. if ((a == 1) || (nb_dec == 1))
  220. a += 1;
  221. else
  222. a += 2;
  223. }
  224. }
  225. }
  226. }
  227. void Fl_Knob::draw_cursor(const int ox,const int oy,const int side) {
  228. float rds,cur,cx,cy;
  229. double angle;
  230. // rds = (side-40) * _capsize / 100.0;
  231. rds=side;
  232. cur = _percent * rds / 2;
  233. // cx = ox + side / 2;
  234. // cy = oy + side / 2;
  235. cx = ox;cy = oy;
  236. angle = (a2-a1)*(value()-minimum())/(maximum()-minimum()) + a1;
  237. fl_push_matrix();
  238. fl_scale(1,1);
  239. fl_translate(cx,cy);
  240. fl_rotate(-angle);
  241. fl_translate(0,rds-cur-2.0);
  242. if (_type<LINELIN)
  243. {
  244. fl_begin_polygon();
  245. fl_color(selection_color());
  246. fl_circle(0.0,0.0,cur);
  247. fl_end_polygon();
  248. fl_begin_loop();
  249. fl_color(FL_BLACK);
  250. fl_circle(0.0,0.0,cur);
  251. fl_end_loop();
  252. }
  253. else
  254. {
  255. fl_begin_polygon();
  256. fl_color(selection_color());
  257. fl_vertex(-1.5,-cur);
  258. fl_vertex(-1.5,cur);
  259. fl_vertex(1.5,cur);
  260. fl_vertex(1.5,-cur);
  261. fl_end_polygon();
  262. fl_begin_loop();
  263. fl_color(FL_BLACK);
  264. fl_vertex(-1.5,-cur);
  265. fl_vertex(-1.5,cur);
  266. fl_vertex(1.5,cur);
  267. fl_vertex(1.5,-cur);
  268. fl_end_loop();
  269. }
  270. fl_pop_matrix();
  271. }
  272. void Fl_Knob::type(int ty) {
  273. _type = ty;
  274. }
  275. void Fl_Knob::cursor(const int pc) {
  276. _percent = (float)pc/100.0;
  277. if (_percent < 0.05) _percent = 0.05;
  278. if (_percent > 1.0) _percent = 1.0;
  279. if (visible()) damage(FL_DAMAGE_CHILD);
  280. }
  281. void Fl_Knob::scaleticks(const int tck) {
  282. _scaleticks = tck;
  283. if (_scaleticks < 0) _scaleticks = 0;
  284. if (_scaleticks > 31) _scaleticks = 31;
  285. if (visible()) damage(FL_DAMAGE_ALL);
  286. }
  287. void Fl_Knob::capsize(const float percent) {
  288. if (percent > 100) return;
  289. if (percent < 40) return;
  290. _capsize = percent;
  291. }
  292. void Fl_Knob::capcolor(const Fl_Color col) {
  293. uchar rr,gg,bb;
  294. Fl::get_color(col,rr,gg,bb);
  295. _capr = rr;
  296. _capg = gg;
  297. _capb = bb;
  298. }
  299. void Fl_Knob::capcolor(const uchar cr,const uchar cg,const uchar cb) {
  300. _capr = cr;
  301. _capg = cg;
  302. _capb = cb;
  303. }