Tales from the Evil Empire

Bertrand Le Roy's blog

News


Bertrand Le Roy

BoudinFatal's Gamercard

Tales from the Evil Empire - Blogged

Blogs I read

My other stuff

Archives

How to multiply a Unit by a number?

The Unit type exists to represent a length, and contains two different informations: a value and a unit or type. The unit can be absolute (pixels, centimeters, etc.) or relative (percentage, em). They are not lengths in the physical sense because in the relative case, they vary depending on the context. This is just how HTML works with lengths.
So every property that will end up representing a length should be of type Unit.
Now, while Unit is a value type (a struct, if you prefer, as opposed to a class), it lacks the basic arithmetic operators. You can't add two Units, but that's normal, because they may have different units (again, they are not lengths in the physical sense), but you can't multiply them by a number either without writing some code.
An example where you would want to do that is for example the Menu control where we have the possibility to indent the submenus. A menu of depth three will have to be indented by three times the indent property value.
We're doing it more or less this way:
 

Unit Multiply(Unit indent, int depth) {
 
if
(indent.IsEmpty) {
   
return Unit
.Empty;
  }
 
if
(indent.Value == 0) {
   
return
indent;
  }

 
double
indentValue = indent.Value * depth;
 
// I'd love not to hardcode this but Unit.MaxValue is currently private.
 
if
(indentValue < 32767) {
   
return new Unit
(indentValue, indent.Type);
  }
 
else
{
    return
new Unit
(32767, indent.Type);
  }
}

Comments

Eddie Garmon said:

Instead of hard coding just add this to your class...

private static int _UnitMaxValue = (int)typeof(Unit).GetField("MaxValue", BindingFlags.NonPublic | BindingFlags.Static).GetValue(new Unit(0));

Its only evaluated once, and of if needed.

Eddie
# January 25, 2005 9:29 PM

Bertrand Le Roy said:

Eddie, that is an excellent point. Thanks!
# January 25, 2005 10:11 PM