public RgbaColor(float red, float green, float blue, float alpha = (float)1.0) : this() { Red = Math.Clamp(red, 0, 255); Green = Math.Clamp(green, 0, 255); Blue = Math.Clamp(blue, 0, 255); Alpha = Math.Clamp(alpha, 0, 255); }
/// <summary> /// Return true if the value given is allowed for the field given. This uses the hints from the GUI /// system to decide what is and isn't allowed. (For example if a GUI slider goes from 10 to 20 at /// increments of 2, then a value of 17 is not something you could achieve in the GUI, being only able /// to go from 16 to 18 skipping over 17, and therefore this routine would return false for trying to /// set it to 17). /// <br/><br/> /// Note that the value passed in may be altered (which is why it's ref) when it's not /// exactly legal, but it's CLOSE ENOUGH to be coerced into a legal value. For example, /// you set a slider to 10.45 and the slider only allows values on the 0.5 marks like 10, 10.5, 11. etc. /// Rather than deny the attempt, the value will be nudged to the nearest legal value. /// </summary> /// <param name="field">Which KSPField is being checked?</param> /// <param name="newVal">What is the value it's being set to? It is possible to /// alter the value to an acceptable replacement which is why it passes by ref</param> /// <param name="except">An exception you can choose to throw if you want, or null if the value is legal.</param> /// <returns>Is it legal?</returns> private bool IsLegalValue(BaseField field, ref object newVal, out KOSException except) { except = null; bool isLegal = true; Type fType = field.FieldInfo.FieldType; object convertedVal = newVal; if (!IsEditable(field)) { except = new KOSInvalidFieldValueException("Field is read-only"); return(false); } if (!newVal.GetType().IsSubclassOf(fType)) { try { convertedVal = Convert.ChangeType(newVal, fType); } catch (InvalidCastException) { except = new KOSCastException(newVal.GetType(), fType); return(false); } catch (FormatException) { except = new KOSCastException(newVal.GetType(), fType); return(false); } } List <UI_Control> controls = GetFieldControls(field); // It's really normal for there to be only one control on a KSPField, but because // it's technically possible to have more than one according to the structure of // the API, this loop is here to check all of "them": foreach (UI_Control control in controls) { // Some of these are subclasses of each other, so don't change this to an if/else. // It's a series of if's on purpose so it checks all classes the control is derived from. if (control is UI_Toggle) { // Seems there's nothing to check here, but maybe later there will be? } if (control is UI_Label) { except = new KOSInvalidFieldValueException("Labels are read-only objects that can't be changed"); isLegal = false; } var vector2 = control as UI_Vector2; if (vector2 != null) { // I have no clue what this actually looks like in the UI? What is a // user editable 2-D vector widget? I've never seen this before. if (convertedVal != null) { var vec2 = (Vector2)convertedVal; if (vec2.x < vector2.minValueX || vec2.x > vector2.maxValueX || vec2.y < vector2.minValueY || vec2.y > vector2.maxValueY) { except = new KOSInvalidFieldValueException("Vector2 is outside of allowed range of values"); isLegal = false; } } } var range = control as UI_FloatRange; if (range != null) { float val = Convert.ToSingle(convertedVal); val = Math.ClampToIndent(val, range.minValue, range.maxValue, range.stepIncrement); convertedVal = Convert.ToDouble(val); } if (!isLegal) { break; } } newVal = convertedVal; return(isLegal); }