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.

364 lines
7.8KB

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