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