Skip to content

Instantly share code, notes, and snippets.

@redent
Last active August 29, 2015 14:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save redent/9c9480e95e59b75d4d3a to your computer and use it in GitHub Desktop.
Save redent/9c9480e95e59b75d4d3a to your computer and use it in GitHub Desktop.
Sample code for using Code Icons created by PaintCode. CodeIconButton can be used from Storyboard and can assign IconColor, IconSize and IconType directly from the interface builder. See SampleIcon to see how declare icons.
using System;
using System.Drawing;
using MonoTouch.UIKit;
namespace TwinCoders.TouchUtils.CodeViews
{
public abstract class CodeIcon : CodeImage
{
public UIColor FillColor { get; set; }
public float WidthHeightProportion { get; private set; }
protected CodeIcon(float widthHeightProportion)
{
FillColor = UIColor.Gray;
WidthHeightProportion = widthHeightProportion;
}
protected override void Draw(SizeF size)
{
Draw(FrameFromSize(size, WidthHeightProportion), FillColor);
}
protected virtual void Draw(SizeF size, UIColor fillColor) {
Draw(FrameFromSize(size, WidthHeightProportion), fillColor);
}
public UIImage AsImage(SizeF size, UIColor color)
{
return AsImage(size, () => Draw(size, color));
}
protected abstract void Draw(RectangleF frame, UIColor fillColor);
/// <summary>
/// Obtains a frame to draw the icon without distortion with the specified proportion based
/// on the original desired
/// </summary>
/// <param name="sizeToAdjust"></param>
/// <param name="widthHeightProportion"></param>
/// <returns></returns>
protected static RectangleF FrameFromSize(SizeF sizeToAdjust, float widthHeightProportion = 1.0f)
{
if (widthHeightProportion < 0)
widthHeightProportion = 1;
var sizeToAdjustProportion = sizeToAdjust.Width/sizeToAdjust.Height;
SizeF adjustedSize;
if (sizeToAdjustProportion > widthHeightProportion)
adjustedSize = new SizeF(sizeToAdjust.Height*widthHeightProportion,
sizeToAdjust.Height);
else
adjustedSize = new SizeF(sizeToAdjust.Width,
sizeToAdjust.Width/widthHeightProportion);
var adjustedOrigin = new PointF(
Math.Abs(sizeToAdjust.Width - adjustedSize.Width)/2,
Math.Abs(sizeToAdjust.Height - adjustedSize.Height)/2);
return new RectangleF(adjustedOrigin, adjustedSize);
}
}
}
using System;
using TwinCoders.TouchUtils.UIElements;
using MonoTouch.Foundation;
using System.Drawing;
using MonoTouch.UIKit;
namespace TwinCoders.TouchUtils.CodeViews
{
[Register("CodeIconButton")]
public class CodeIconButton : StyledButton
{
[Export]
public string CodeIconType { get; set; }
[Export]
public SizeF CodeIconSize { get; set; }
[Export]
public UIColor IconColor { get; set; }
[Export]
public UIColor HighlightedIconColor { get; set; }
[Export]
public UIColor SelectedIconColor { get; set; }
[Export]
public UIColor DisabledIconColor { get; set; }
public Type CodeIcon { get; set; }
[Export("initWithCoder:")]
public CodeIconButton(NSCoder coder) : base(coder) {
CodeIconSize = new SizeF(20, 20);
IconColor = UIColor.White;
HighlightedIconColor = UIColor.White;
}
[Export("init")]
public CodeIconButton() {}
public CodeIconButton(IntPtr handle) : base(handle) {}
public override void AwakeFromNib()
{
base.AwakeFromNib();
UpdateIcon();
}
public void UpdateIcon() {
Type iconType = CodeIcon ?? CodeIconGallery.GetIconType(CodeIconType);
this.AddCodeIconImage(iconType, CodeIconSize, IconColor, HighlightedIconColor, SelectedIconColor, DisabledIconColor);
}
}
}
using System;
using System.Drawing;
using MonoTouch.UIKit;
using System.Collections.Generic;
using TwinCoders.TouchUtils.UIElements;
namespace TwinCoders.TouchUtils.CodeViews
{
public static class CodeIconButtonUtils
{
/// <summary>
/// Creates a button which icon is a CodeIcon image
/// </summary>
/// <typeparam name="T">CodeIcon type. It requires a constructor that takes a UIColor parameter</typeparam>
/// <param name="iconSize">Size of the icon image contained in the button</param>
/// <param name="iconColor">Color of the icon for normal state</param>
/// <param name="highlightedColor">Color of the icon for highlighted state</param>
/// <param name="selectedColor">Color of the icon for selected state</param>
/// <param name="disabledColor">Color of the icon for disabled state</param>
/// <param name = "leftAligned">Indicates if the icon should be left aligned or center</param>
/// <returns></returns>
public static StyledButton CreateCodeIconButton<T>(SizeF iconSize,
UIColor iconColor, UIColor highlightedColor = null,
UIColor selectedColor = null, UIColor disabledColor = null,
bool leftAligned = true) where T : CodeIcon
{
var button = leftAligned ? new LeftAlignedButton() : new StyledButton();
button.AddCodeIconImage<T>(iconSize, iconColor, highlightedColor, selectedColor, disabledColor);
return button;
}
public static CenteredImageButton CreateCenteredCodeIconButton<T>(SizeF iconSize,
UIColor iconColor, UIColor highlightedColor = null,
UIColor selectedColor = null, UIColor disabledColor = null) where T : CodeIcon {
var button = new CenteredImageButton();
button.AddCodeIconImage<T>(iconSize, iconColor, highlightedColor, selectedColor, disabledColor);
return button;
}
public static void AddCodeIconImage<T>(this UIButton button, SizeF iconSize,
UIColor iconColor, UIColor highlightedColor = null,
UIColor selectedColor = null, UIColor disabledColor = null) where T : CodeIcon {
button.AddCodeIconImage(typeof(T), iconSize, iconColor, highlightedColor, selectedColor, disabledColor);
}
public static void AddCodeIconImage(this UIButton button, Type type, SizeF iconSize,
UIColor iconColor, UIColor highlightedColor = null,
UIColor selectedColor = null, UIColor disabledColor = null) {
var stateColors = new List<Tuple<UIControlState, UIColor>>();
if (iconColor != null)
stateColors.Add(new Tuple<UIControlState, UIColor>(UIControlState.Normal, iconColor));
if (highlightedColor != null)
stateColors.Add(new Tuple<UIControlState, UIColor>(UIControlState.Highlighted, highlightedColor));
if (selectedColor != null)
stateColors.Add(new Tuple<UIControlState, UIColor>(UIControlState.Selected, selectedColor));
if (disabledColor != null)
stateColors.Add(new Tuple<UIControlState, UIColor>(UIControlState.Disabled, disabledColor));
button.AddCodeIconImage(type, iconSize, stateColors.ToArray());
}
public static void AddCodeIconImage<T>(this UIButton button, SizeF iconSize,
params Tuple<UIControlState, UIColor>[] stateColors) where T : CodeIcon
{
button.AddCodeIconImage(typeof(T), iconSize, stateColors);
}
public static void AddCodeIconImage(this UIButton button, Type type, SizeF iconSize,
params Tuple<UIControlState, UIColor>[] stateColors)
{
var icon = (CodeIcon) Activator.CreateInstance(type);
foreach (var tuple in stateColors)
{
var state = tuple.Item1;
var color = tuple.Item2;
icon.FillColor = color;
button.SetImage(icon.AsImage(iconSize), state);
}
}
}
}
using System;
using System.Collections.Generic;
namespace TwinCoders.TouchUtils.CodeViews
{
/// Utility class created to change the icon type on runtime (usefull when downloading the icon type from a WS for example)
public static class CodeIconGallery
{
static readonly Dictionary<string, Type> _codeIconDictionary = new Dictionary<string, Type>();
public static void RegisterIcon<T>() where T : CodeIcon, new() {
_codeIconDictionary[typeof(T).Name] = typeof(T);
}
public static void RegisterIcon(Type iconType) {
_codeIconDictionary[iconType.Name] = iconType;
}
public static Type GetIconType(string iconName) {
if (iconName == null)
return null;
Type type = null;
return _codeIconDictionary.TryGetValue(iconName, out type) ? type : null;
}
public static CodeIcon CreateInstance(string iconName) {
var iconType = GetIconType(iconName);
return iconType != null ? (CodeIcon)Activator.CreateInstance(iconType) : null;
}
}
}
using System.Drawing;
using MonoTouch.UIKit;
using System;
namespace TwinCoders.TouchUtils.CodeViews
{
public abstract class CodeImage
{
/// <summary>
/// Draws the icon in a graphics context contained in the specified size
/// </summary>
/// <param name="size">Size of the graphics context frame</param>
protected abstract void Draw(SizeF size);
public UIImage AsImage(SizeF size)
{
return AsImage(size, () => Draw(size));
}
public static UIImage AsImage(SizeF size, Action drawMethod) {
if (size == SizeF.Empty)
return null;
UIGraphics.BeginImageContextWithOptions(size, false, UIScreen.MainScreen.Scale);
drawMethod();
var image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return image;
}
}
}
using TwinCoders.TouchUtils.CodeViews;
using System.Drawing;
using MonoTouch.UIKit;
using MonoTouch.CoreGraphics;
namespace SalesForce.Touch.Views.Icons
{
public class PencilIcon : CodeIcon
{
public PencilIcon() : base(107/110f)// 107 width / 110 height proportion
{
}
protected override void Draw(RectangleF frame, UIColor fillColor)
{
UIBezierPath bezierPath = new UIBezierPath();
bezierPath.MoveTo(new PointF(frame.GetMinX() + 0.97850f * frame.Width, frame.GetMinY() + 0.20026f * frame.Height));
bezierPath.AddLineTo(new PointF(frame.GetMinX() + 0.88669f * frame.Width, frame.GetMinY() + 0.29261f * frame.Height));
bezierPath.AddLineTo(new PointF(frame.GetMinX() + 0.71280f * frame.Width, frame.GetMinY() + 0.12663f * frame.Height));
bezierPath.AddLineTo(new PointF(frame.GetMinX() + 0.80704f * frame.Width, frame.GetMinY() + 0.02637f * frame.Height));
bezierPath.AddCurveToPoint(new PointF(frame.GetMinX() + 0.89884f * frame.Width, frame.GetMinY() + 0.03446f * frame.Height), new PointF(frame.GetMinX() + 0.85649f * frame.Width, frame.GetMinY() + -0.02244f * frame.Height), new PointF(frame.GetMinX() + 0.89884f * frame.Width, frame.GetMinY() + 0.03446f * frame.Height));
bezierPath.AddLineTo(new PointF(frame.GetMinX() + 0.97681f * frame.Width, frame.GetMinY() + 0.11772f * frame.Height));
bezierPath.AddCurveToPoint(new PointF(frame.GetMinX() + 0.97850f * frame.Width, frame.GetMinY() + 0.20026f * frame.Height), new PointF(frame.GetMinX() + 1.02449f * frame.Width, frame.GetMinY() + 0.16490f * frame.Height), new PointF(frame.GetMinX() + 0.97850f * frame.Width, frame.GetMinY() + 0.20026f * frame.Height));
bezierPath.AddLineTo(new PointF(frame.GetMinX() + 0.97850f * frame.Width, frame.GetMinY() + 0.20026f * frame.Height));
bezierPath.ClosePath();
bezierPath.MoveTo(new PointF(frame.GetMinX() + 0.26807f * frame.Width, frame.GetMinY() + 0.90524f * frame.Height));
bezierPath.AddLineTo(new PointF(frame.GetMinX() + 0.07436f * frame.Width, frame.GetMinY() + 0.74945f * frame.Height));
bezierPath.AddLineTo(new PointF(frame.GetMinX() + 0.64521f * frame.Width, frame.GetMinY() + 0.18171f * frame.Height));
bezierPath.AddLineTo(new PointF(frame.GetMinX() + 0.83321f * frame.Width, frame.GetMinY() + 0.35405f * frame.Height));
bezierPath.AddLineTo(new PointF(frame.GetMinX() + 0.26807f * frame.Width, frame.GetMinY() + 0.90524f * frame.Height));
bezierPath.AddLineTo(new PointF(frame.GetMinX() + 0.26807f * frame.Width, frame.GetMinY() + 0.90524f * frame.Height));
bezierPath.ClosePath();
bezierPath.MoveTo(new PointF(frame.GetMinX() + 0.01126f * frame.Width, frame.GetMinY() + 0.99568f * frame.Height));
bezierPath.AddLineTo(new PointF(frame.GetMinX() + 0.00406f * frame.Width, frame.GetMinY() + 0.99841f * frame.Height));
bezierPath.AddLineTo(new PointF(frame.GetMinX() + 0.00434f * frame.Width, frame.GetMinY() + 0.81971f * frame.Height));
bezierPath.AddLineTo(new PointF(frame.GetMinX() + 0.19431f * frame.Width, frame.GetMinY() + 0.96678f * frame.Height));
bezierPath.AddLineTo(new PointF(frame.GetMinX() + 0.01126f * frame.Width, frame.GetMinY() + 0.99568f * frame.Height));
bezierPath.AddLineTo(new PointF(frame.GetMinX() + 0.01126f * frame.Width, frame.GetMinY() + 0.99568f * frame.Height));
bezierPath.ClosePath();
bezierPath.MiterLimit = 4;
fillColor.SetFill();
bezierPath.Fill();
}
}
}
using MonoTouch.UIKit;
using MonoTouch.Foundation;
using TwinCoders.TouchUtils.Extensions;
using System.Drawing;
using System;
namespace TwinCoders.TouchUtils.UIElements
{
[Register("StyleButton")]
public class StyledButton : UIButton
{
[Export("initWithCoder:")]
public StyledButton(NSCoder coder) : base(coder) {
_backgroundColor = base.BackgroundColor;
}
[Export("init")]
public StyledButton() {}
public StyledButton(IntPtr handle) : base(handle) {}
[Export] public UIColor HighlightedBackgroundColor { get; set; }
[Export] public UIColor SelectedBackgroundColor { get; set; }
[Export] public UIColor HighlightedSelectedBackgroundColor { get; set; }
[Export] public UIColor DisabledBackgroundColor { get; set; }
[Export] public UIColor SelectedDisabledBackgroundColor { get; set; }
public override bool Highlighted
{
get { return base.Highlighted; }
set
{
base.Highlighted = value;
RefreshBackgroundColor();
}
}
public override bool Selected
{
get { return base.Selected; }
set
{
base.Selected = value;
RefreshBackgroundColor();
}
}
public override bool Enabled
{
get { return base.Enabled; }
set
{
base.Enabled = value;
RefreshBackgroundColor();
}
}
private UIColor _backgroundColor;
public override UIColor BackgroundColor
{
get { return base.BackgroundColor; }
set
{
_backgroundColor = value;
base.BackgroundColor = value;
}
}
public void RefreshBackgroundColor() {
var color = _backgroundColor ?? base.BackgroundColor;
if (Selected && !Enabled)
color = SelectedDisabledBackgroundColor ?? DisabledBackgroundColor ?? (SelectedBackgroundColor ?? HighlightedBackgroundColor ?? BackgroundColor ?? UIColor.Clear).ColorWithAlpha(0.5f);
else if (!Enabled)
color = DisabledBackgroundColor ?? (color ?? UIColor.Clear).ColorWithAlpha(0.5f);
else if (Selected && Highlighted && HighlightedSelectedBackgroundColor != null)
color = HighlightedSelectedBackgroundColor;
else if (Selected && SelectedBackgroundColor != null)
color = SelectedBackgroundColor;
else if (Highlighted)
color = HighlightedBackgroundColor ?? (color ?? UIColor.Clear).DarkerColor(0.2f);
// Use highlighted color if selected color is null and status is selected
else if (Selected && HighlightedBackgroundColor != null && SelectedBackgroundColor == null)
color = HighlightedBackgroundColor;
base.BackgroundColor = color;
}
public override System.Drawing.SizeF IntrinsicContentSize
{
get
{
var size = base.IntrinsicContentSize;
if (string.IsNullOrEmpty(Title(State)))
return size;
var inset = TitleEdgeInsets;
return new SizeF(size.Width + inset.Left + inset.Right,
size.Height + inset.Top + inset.Bottom);
}
}
}
}
using System;
using MonoTouch.UIKit;
namespace TwinCoders.TouchUtils.Extensions
{
/// Utility class for creating colors from RGB strings and creating darker or lighter versions of an existing color
public static class UIColorExtensions
{
public static UIColor FromHex(int hexValue)
{
return UIColor.FromRGB(
(((hexValue & 0xFF0000) >> 16) / 255.0f),
(((hexValue & 0xFF00) >> 8) / 255.0f),
((hexValue & 0xFF) / 255.0f)
);
}
public static UIColor FromHexString(string hexValue, float alpha = 1.0f)
{
var colorString = hexValue.Replace("#", "");
if (alpha > 1.0f)
{
alpha = 1.0f;
}
else if (alpha < 0.0f)
{
alpha = 0.0f;
}
float red, green, blue;
switch (colorString.Length)
{
case 3: // #RGB
{
red = Convert.ToInt32(string.Format("{0}{0}", colorString.Substring(0, 1)), 16) / 255f;
green = Convert.ToInt32(string.Format("{0}{0}", colorString.Substring(1, 1)), 16) / 255f;
blue = Convert.ToInt32(string.Format("{0}{0}", colorString.Substring(2, 1)), 16) / 255f;
return UIColor.FromRGBA(red, green, blue, alpha);
}
case 6: // #RRGGBB
{
red = Convert.ToInt32(colorString.Substring(0, 2), 16) / 255f;
green = Convert.ToInt32(colorString.Substring(2, 2), 16) / 255f;
blue = Convert.ToInt32(colorString.Substring(4, 2), 16) / 255f;
return UIColor.FromRGBA(red, green, blue, alpha);
}
default:
throw new ArgumentOutOfRangeException(string.Format("Invalid color value {0} is invalid. It should be a hex value of the form #RBG, #RRGGBB", hexValue));
}
}
public static UIColor DarkerColor(this UIColor c, float percentage = 0.2f) {
float h, s, b, a;
c.GetHSBA(out h, out s, out b, out a);
return UIColor.FromHSBA(h, s, Math.Max(Math.Min(b * (1 - percentage), 1.0f), 0.0f), a);
}
public static UIColor LighterColor(this UIColor c, float percentage = 0.2f) {
float h, s, b, a;
c.GetHSBA(out h, out s, out b, out a);
return UIColor.FromHSBA(h, s, Math.Max(Math.Min(b * (1 + percentage), 1.0f), 0.0f), a);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment