2011-07-25 00:21:50 +04:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
2015-01-19 18:09:40 +03:00
|
|
|
using Foundation;
|
|
|
|
using UIKit;
|
2011-07-25 00:21:50 +04:00
|
|
|
using QuartzSample;
|
2015-01-19 18:09:40 +03:00
|
|
|
using CoreGraphics;
|
2011-07-25 00:21:50 +04:00
|
|
|
|
|
|
|
namespace QuartzSample
|
|
|
|
{
|
|
|
|
public partial class QuartzBlendingViewController : QuartzViewController
|
|
|
|
{
|
|
|
|
#region Constructors
|
2015-01-19 18:09:40 +03:00
|
|
|
|
|
|
|
// The IntPtr and initWithCoder constructors are required for items that need
|
2011-07-25 00:21:50 +04:00
|
|
|
// to be able to be created from a xib rather than from managed code
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
public QuartzBlendingViewController (IntPtr handle) : base (handle)
|
|
|
|
{
|
|
|
|
Initialize ();
|
|
|
|
}
|
|
|
|
|
|
|
|
[Export ("initWithCoder:")]
|
|
|
|
public QuartzBlendingViewController (NSCoder coder) : base (coder)
|
|
|
|
{
|
|
|
|
Initialize ();
|
|
|
|
}
|
|
|
|
|
|
|
|
public QuartzBlendingViewController () : base ("QuartzBlendingViewController", null)
|
|
|
|
{
|
|
|
|
Initialize ();
|
|
|
|
}
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
public QuartzBlendingViewController (CreateView creator, string title, string info) : base (creator, "QuartzBlendingViewController", title, info)
|
|
|
|
{
|
|
|
|
Array.Sort (Colors, ColorSortByLuminance);
|
|
|
|
}
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
void Initialize ()
|
|
|
|
{
|
|
|
|
}
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
#endregion
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
static UIColor [] Colors = new UIColor [] {
|
|
|
|
UIColor.Red,
|
|
|
|
UIColor.Green,
|
|
|
|
UIColor.Blue,
|
|
|
|
UIColor.Yellow,
|
|
|
|
UIColor.Magenta,
|
|
|
|
UIColor.Cyan,
|
|
|
|
UIColor.Orange,
|
|
|
|
UIColor.Purple,
|
|
|
|
UIColor.Brown,
|
|
|
|
UIColor.White,
|
|
|
|
UIColor.LightGray,
|
|
|
|
UIColor.DarkGray,
|
|
|
|
UIColor.Black
|
|
|
|
};
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
static string [] BlendModes = new string [] {
|
|
|
|
"Normal",
|
|
|
|
"Multiply",
|
|
|
|
"Screen",
|
|
|
|
"Overlay",
|
|
|
|
"Darken",
|
|
|
|
"Lighten",
|
|
|
|
"ColorDodge",
|
|
|
|
"ColorBurn",
|
|
|
|
"SoftLight",
|
|
|
|
"HardLight",
|
|
|
|
"Difference",
|
|
|
|
"Exclusion",
|
|
|
|
"Hue",
|
|
|
|
"Saturation",
|
|
|
|
"Color",
|
|
|
|
"Luminosity",
|
|
|
|
// Porter-Duff Blend Modes
|
|
|
|
"Clear",
|
|
|
|
"Copy",
|
|
|
|
"SourceIn",
|
|
|
|
"SourceOut",
|
|
|
|
"SourceAtop",
|
|
|
|
"DestinationOver",
|
|
|
|
"DestinationIn",
|
|
|
|
"DestinationOut",
|
|
|
|
"DestinationAtop",
|
|
|
|
"XOR",
|
|
|
|
"PlusDarker",
|
|
|
|
"PlusLighter",
|
|
|
|
};
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
public override void ViewDidLoad ()
|
|
|
|
{
|
|
|
|
base.ViewDidLoad ();
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
picker.Model = new BlendSelector (this);
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
var qbv = (QuartzBlendingView) quartzView;
|
|
|
|
picker.Select (Array.IndexOf (Colors, qbv.DestinationColor), 0, false);
|
|
|
|
picker.Select (Array.IndexOf (Colors, qbv.SourceColor), 1, false);
|
|
|
|
picker.Select ((int) qbv.BlendMode, 2, false);
|
|
|
|
}
|
2015-01-19 18:09:40 +03:00
|
|
|
|
|
|
|
static nfloat LuminanceForColor (UIColor color)
|
2011-07-25 00:21:50 +04:00
|
|
|
{
|
|
|
|
CGColor cgcolor = color.CGColor;
|
|
|
|
var components = cgcolor.Components;
|
2015-01-19 18:09:40 +03:00
|
|
|
nfloat luminance = 0;
|
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
switch (cgcolor.ColorSpace.Model){
|
|
|
|
case CGColorSpaceModel.Monochrome:
|
|
|
|
// For grayscale colors, the luminance is the color value
|
|
|
|
luminance = components[0];
|
|
|
|
break;
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
case CGColorSpaceModel.RGB:
|
|
|
|
// For RGB colors, we calculate luminance assuming sRGB Primaries as per
|
|
|
|
// http://en.wikipedia.org/wiki/Luminance_(relative)
|
|
|
|
luminance = 0.2126f * components[0] + 0.7152f * components[1] + 0.0722f * components[2];
|
|
|
|
break;
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
default:
|
|
|
|
// We don't implement support for non-gray, non-rgb colors at this time.
|
|
|
|
// Since our only consumer is colorSortByLuminance, we return a larger than normal
|
|
|
|
// value to ensure that these types of colors are sorted to the end of the list.
|
|
|
|
luminance = 2.0f;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return luminance;
|
|
|
|
}
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
// Simple comparison function that sorts the two (presumed) UIColors according to their luminance value.
|
|
|
|
static int ColorSortByLuminance (UIColor color1, UIColor color2)
|
|
|
|
{
|
2015-01-19 18:09:40 +03:00
|
|
|
nfloat luminance1 = LuminanceForColor(color1);
|
|
|
|
nfloat luminance2 = LuminanceForColor(color2);
|
|
|
|
|
|
|
|
if (luminance1 == luminance2)
|
2011-07-25 00:21:50 +04:00
|
|
|
return 0;
|
|
|
|
else if (luminance1 < luminance2)
|
|
|
|
return -1;
|
|
|
|
else
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-01-19 18:09:40 +03:00
|
|
|
public class BlendSelector : UIPickerViewModel
|
2011-07-25 00:21:50 +04:00
|
|
|
{
|
|
|
|
QuartzBlendingViewController parent;
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
public BlendSelector (QuartzBlendingViewController parent)
|
|
|
|
{
|
|
|
|
this.parent = parent;
|
|
|
|
}
|
2015-01-19 18:09:40 +03:00
|
|
|
|
|
|
|
public override nint GetComponentCount (UIPickerView picker){
|
2011-07-25 00:21:50 +04:00
|
|
|
return 3;
|
|
|
|
}
|
2015-01-19 18:09:40 +03:00
|
|
|
|
|
|
|
public override nint GetRowsInComponent (UIPickerView picker, nint component)
|
2011-07-25 00:21:50 +04:00
|
|
|
{
|
|
|
|
if (component == 0 || component == 1)
|
|
|
|
return Colors.Length;
|
|
|
|
return BlendModes.Length;
|
|
|
|
}
|
2015-01-19 18:09:40 +03:00
|
|
|
|
|
|
|
public override nfloat GetComponentWidth (UIPickerView picker, nint component)
|
2011-07-25 00:21:50 +04:00
|
|
|
{
|
|
|
|
if (component == 0 || component == 1)
|
|
|
|
return 48f;
|
|
|
|
return 192f;
|
2015-01-19 18:09:40 +03:00
|
|
|
}
|
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
const int kColorTag = 1;
|
|
|
|
const int kLabelTag = 1;
|
2015-01-19 18:09:40 +03:00
|
|
|
|
|
|
|
public override UIView GetView (UIPickerView picker, nint row, nint component, UIView view)
|
2011-07-25 00:21:50 +04:00
|
|
|
{
|
|
|
|
var size = picker.RowSizeForComponent (component);
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
if (component == 0 || component == 1){
|
|
|
|
if (view == null || view.Tag != kColorTag){
|
2015-01-19 18:09:40 +03:00
|
|
|
view = new UIView (new CGRect (0, 0, size.Width-4, size.Height-4)){
|
2011-07-25 00:21:50 +04:00
|
|
|
Tag = kColorTag
|
|
|
|
};
|
|
|
|
}
|
|
|
|
view.BackgroundColor = Colors [row];
|
|
|
|
} else {
|
|
|
|
if (view == null || view.Tag != kLabelTag){
|
2015-01-19 18:09:40 +03:00
|
|
|
view = new UILabel (new CGRect (0, 0, size.Width-4, size.Height-4)){
|
2011-07-25 00:21:50 +04:00
|
|
|
Tag = kLabelTag,
|
|
|
|
Opaque = false,
|
|
|
|
BackgroundColor = UIColor.Clear
|
|
|
|
};
|
|
|
|
}
|
|
|
|
var label = (UILabel) view;
|
|
|
|
label.TextColor = UIColor.Black;
|
|
|
|
label.Text = BlendModes [row];
|
|
|
|
label.Font = UIFont.BoldSystemFontOfSize (18f);
|
|
|
|
}
|
|
|
|
return view;
|
|
|
|
}
|
2015-01-19 18:09:40 +03:00
|
|
|
|
|
|
|
public override void Selected (UIPickerView picker, nint row, nint component)
|
2011-07-25 00:21:50 +04:00
|
|
|
{
|
|
|
|
var qbv = (QuartzBlendingView) parent.quartzView;
|
|
|
|
qbv.DestinationColor = Colors [picker.SelectedRowInComponent (0)];
|
|
|
|
qbv.SourceColor = Colors [picker.SelectedRowInComponent (1)];
|
2015-01-19 18:09:40 +03:00
|
|
|
qbv.BlendMode = (CGBlendMode) (int)picker.SelectedRowInComponent (2);
|
2011-07-25 00:21:50 +04:00
|
|
|
qbv.SetNeedsDisplay ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
public class QuartzBlendingView : QuartzView {
|
|
|
|
public UIColor SourceColor { get; set; }
|
|
|
|
public UIColor DestinationColor { get; set; }
|
|
|
|
public CGBlendMode BlendMode { get; set; }
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
public QuartzBlendingView () : base () {
|
|
|
|
SourceColor = UIColor.White;
|
|
|
|
DestinationColor = UIColor.Black;
|
|
|
|
BlendMode = CGBlendMode.Normal;
|
|
|
|
}
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
public override void DrawInContext (CGContext context)
|
|
|
|
{
|
|
|
|
// Start with a background whose color we don't use in the demo
|
2015-01-19 18:09:40 +03:00
|
|
|
context.SetFillColor (0.2f, 1);
|
2011-07-25 00:21:50 +04:00
|
|
|
context.FillRect (Bounds);
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
// We want to just lay down the background without any blending so we use the Copy mode rather than Normal
|
|
|
|
context.SetBlendMode(CGBlendMode.Copy);
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
// Draw a rect with the "background" color - this is the "Destination" for the blending formulas
|
2015-01-19 18:09:40 +03:00
|
|
|
context.SetFillColor (DestinationColor.CGColor);
|
|
|
|
context.FillRect(new CGRect (110, 20, 100, 100));
|
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
// Set up our blend mode
|
|
|
|
context.SetBlendMode (BlendMode);
|
2015-01-19 18:09:40 +03:00
|
|
|
|
2011-07-25 00:21:50 +04:00
|
|
|
// And draw a rect with the "foreground" color - this is the "Source" for the blending formulas
|
2015-01-19 18:09:40 +03:00
|
|
|
context.SetFillColor (SourceColor.CGColor);
|
|
|
|
context.FillRect (new CGRect (60, 45, 200, 50));
|
2011-07-25 00:21:50 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|