[MPlayer-dev-eng] [PATCH] GUI: Implement a true rotary potmeter

Hans-Dieter Kosch hdkosch at kabelbw.de
Wed Apr 2 04:24:47 CEST 2014


Ingo Brückl wrote:

> Hans-Dieter Kosch wrote on Mon, 31 Mar 2014 01:44:10 +0200:

> I have a few first questions and comments though.
> 
>> +                   double dx = X - item->x - item->width / 2;
>> +                   double dy = Y - item->y - item->height / 2;
>> +
>> +                   last_rpotmeter_angle = (dx == 0 && dy == 0) ? 0 : (atan2(dx, -dy) + M_PI) / (2*M_PI);
> 
> The variable name (last_rpotmeter_angle) is confusing, since stricly speaking
> it isn't an angle (in degrees).

Oh, yes, convenient naming is sometimes half the coding effort. It's a 
normalised angle 0..1 as stated later in a comment. I do not object against 
finding a better name.

> I was expecting something like "atan2(-dy, dx) / M_PI * 180" here.

All trigonometric functions work with radians, not degrees; so 180 would be M_PI.
That expression calculates in one step the angle mirrored from mathematical 
counter clockwise to physical clockwise, rotates the 0 from middle right to 
center bottom and normalises it to 0..1.
In the beginning, I had it in separate steps for better understanding, but 
finally, I didn't dare posting such exploded code. The other [hv]potmeter 
calculations are also very compactly coded.

> Well, it seems that you've fixed where 0% is. Have you given plastic skin
> a go? ;-)

Not yet, I'll look.

> It is hard to say where 0 for a poti should be (I actually don't remember the
> old radios with potis that snapped and clicked into place), but since the
> zero point is arbitrary I'd say we need a different approach. (And think of
> these modern "endless" rotary potis you have nowadays, a 1-phase potmeter or
> a potmeter without mark/button. Where is its 0%?)

Right, the zero point is arbitrary, I thought about this, too. Traditional 
mechanical potis have it at center bottom, but I've also seen other species. 
Specifying the zero point would need a skin definition and appears somewhat 
luxury to me.

The endless potis are designed for incremental adjusting of different values 
depending on an item selection. The item value, of course, has limits and needs 
a separate display. And it has to be obvious which item is about to be adjusted. 
All this comes from modern complicated narrowly layouted multi function 
interfaces. Do we want such? In the skin definition, the function of a poti is 
clearly assigned.

> I've not completely thought about it, but it seems that we would need some
> additional information about the zero point of a rpotmeter, or mouse clicks
> can't be handled else.

Mouse clicks work like with the other potis, position and value jump to the 
clicked point (GTK GUI).

> A mouse drag simply is a difference to the degree/radian from wsPLMouseButton
> and the item's value should be adjusted according to this difference then.

Dragging purely by difference is WIN GUI behaviour (untested as said). The GTK 
GUI sets the point according to the mouse button down position and proceeds from 
there on; this works like with the other potis.

> For the mouse wheel it's just a simple value adjustment (currently unchecked
> by the way), but a mouse click is tricky.

The wheel is tested to work flawlessly (with all potis).

> Since rpotmeters don't yet exist at the moment, we can set up the rules for
> them without breaking existing skins. However, I want to remain as compatible
> as possible with the other potmeters.
> 
> What do you think?

OK. Compatibility first, but open for any ideas. I regard a rotary poti just 
like a linear one. The difference is that a circle has basically no start and no 
end...

>> +                   // CW angle, 0..1, 0 at center/bottom
> 
> You should be verbose (CW in this case; clockwise?).

Yes, CW (clockwise) and CCW (counter clockwise) are usual abbreviations. I was 
anyway unsure about commenting. I'm used to comprehensively comment my code for 
easy understanding, but found it rarely in MPlayer code.

>> +                   a = FFMAX( a, RPOTMETER_STOP_GAP );
>> +                   a = FFMIN( a, 1-RPOTMETER_STOP_GAP );
>> +                   value = ((a - RPOTMETER_STOP_GAP) / (1-2*RPOTMETER_STOP_GAP)) * 100.0;
> 
> How did you determine RPOTMETER_STOP_GAP?

This is more or less arbitrarily chosen. Its value 1/60 corresponds to 1 minute 
of angle, and matches quite good the 51 image phases of the volume potmeter in 
the 'default' test skin. Traditional mechanical potis have a 270° range, so 
RPOTMETER_STOP_GAP could be 1/8, but this appeared too restrictive to me.

>> +                   // Stop rotating when crossing 0 until crossing in opposite direction
>> +                   if (last_rpotmeter_angle < 0.25 && a > 0.75) rpotmeter_stop = rpotmeter_stop == 1 ? 0 : -1;
>> +                   if (last_rpotmeter_angle > 0.75 && a < 0.25) rpotmeter_stop = rpotmeter_stop == -1 ? 0 : 1;
> 
> Where do the numeric constants (0.25, 0.75) come from?

They separate between the upper and lower half of the potmeter circle. The stop 
gap is in the lower half:

     0.5
0.25   0.75
   0.0|1.0


Hans-Dieter


More information about the MPlayer-dev-eng mailing list