Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mac: Support using transparent background colors for most controls #1969

Merged
merged 1 commit into from
Jun 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions src/Eto.Mac/ColorizeView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ namespace Eto.Mac
class ColorizeView : IDisposable
{
NSImage _image;
CGSize? _realSize;

public Color Color { get; set; }

Expand All @@ -43,7 +42,7 @@ class ColorizeView : IDisposable

public static void Create(ref ColorizeView colorize, Color? color)
{
if (color == null || color.Value.A <= 0)
if (color == null)
{
colorize?.Dispose();
colorize = null;
Expand All @@ -60,9 +59,9 @@ public void Begin(CGRect frame, NSView controlView)
var size = controlView.Frame.Size;
if (size.Width <= 0 || size.Height <= 0)
{
_realSize = null;
return;
}

if (_image == null || size != _image.Size)
{
if (_image != null)
Expand All @@ -71,32 +70,27 @@ public void Begin(CGRect frame, NSView controlView)
_image = new NSImage(size);
}

if (supportsConvertSizeToBacking)
_realSize = controlView.ConvertSizeToBacking(size);
else
_realSize = controlView.ConvertSizeToBase(size);

_image.LockFocusFlipped(!controlView.IsFlipped);
NSGraphicsContext.CurrentContext.GraphicsPort.ClearRect(new CGRect(CGPoint.Empty, size));
}

public void End()
{
if (_image == null || _realSize == null)
if (_image == null)
return;

_image.UnlockFocus();

var ciImage = CIImage.FromCGImage(_image.CGImage);

var cgImage = _image.CGImage;
var ciImage = CIImage.FromCGImage(cgImage);

#pragma warning disable CS0618 // Image => InputImage in Xamarin.Mac 6.6
var filter2 = new CIColorControls();
filter2.SetDefaults();
filter2.Image = ciImage;
filter2.Saturation = 0.0f;
ciImage = (CIImage)filter2.ValueForKey(CIOutputImage);

var filter3 = new CIColorMatrix();
filter3.SetDefaults();
filter3.Image = ciImage;
Expand All @@ -109,13 +103,21 @@ public void End()
filter3.RVector = new CIVector(0, components[0], 0);
filter3.GVector = new CIVector(components[1], 0, 0);
filter3.BVector = new CIVector(0, 0, components[2]);
filter3.AVector = new CIVector(0, 0, 0, cgColor.Alpha);
}
else if (components.Length >= 1)
{
// grayscale
filter3.RVector = new CIVector(0, components[0], 0);
filter3.GVector = new CIVector(components[0], 0, 0);
filter3.BVector = new CIVector(0, 0, components[0]);
}

filter3.AVector = new CIVector(0, 0, 0, cgColor.Alpha);
ciImage = (CIImage)filter3.ValueForKey(CIOutputImage);

// create separate context so we can force using the software renderer, which is more than fast enough for this
var ciContext = CIContext.FromContext(NSGraphicsContext.CurrentContext.GraphicsPort, new CIContextOptions { UseSoftwareRenderer = true });
ciContext.DrawImage(ciImage, new CGRect(CGPoint.Empty, _image.Size), new CGRect(CGPoint.Empty, _realSize.Value));
ciContext.DrawImage(ciImage, new CGRect(CGPoint.Empty, _image.Size), new CGRect(0, 0, cgImage.Width, cgImage.Height));

ciImage.Dispose();
ciContext.Dispose();
Expand Down
20 changes: 7 additions & 13 deletions src/Eto.Mac/Forms/Controls/ButtonHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ static ButtonHandler()
}
}

public class EtoButtonCell : NSButtonCell
public class EtoButtonCell : NSButtonCell, IColorizeCell
{
ColorizeView colorize;
public Color? Color
Expand Down Expand Up @@ -207,19 +207,13 @@ public override void AttachEvent(string id)
}
}

public override Color BackgroundColor
protected override Color DefaultBackgroundColor => ((EtoButtonCell)Control.Cell).Color ?? Control.Cell.BackgroundColor.ToEto();

protected override void SetBackgroundColor(Color? color)
{
get
{
var cell = (EtoButtonCell)Control.Cell;
return cell.Color ?? Colors.Transparent;
}
set
{
var cell = (EtoButtonCell)Control.Cell;
cell.Color = value.A > 0 ? (Color?)value : null;
Control.SetNeedsDisplay();
}
var cell = (EtoButtonCell)Control.Cell;
cell.Color = color;
Control.SetNeedsDisplay();
}

public Image Image
Expand Down
38 changes: 22 additions & 16 deletions src/Eto.Mac/Forms/Controls/ComboBoxHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public EtoComboBox()
}
}

public class EtoCell : NSComboBoxCell
public class EtoCell : NSComboBoxCell, IColorizeCell
{
[Export("tableView:willDisplayCell:forTableColumn:row:")]
public void TableWillDisplayCellForTableColumn(NSTableView tableView, NSCell cell, NSTableColumn tableColumn, nint rowIndex)
Expand All @@ -95,6 +95,25 @@ public void TableWillDisplayCellForTableColumn(NSTableView tableView, NSCell cel
window.SetFrame(frame, true);
}
}

ColorizeView colorize;

public Color? Color
{
get => colorize?.Color;
set => ColorizeView.Create(ref colorize, value);
}

public override void DrawInteriorWithFrame(CGRect cellFrame, NSView inView)
{
colorize?.End();
base.DrawInteriorWithFrame(cellFrame, inView);
}
public override void DrawWithFrame(CGRect cellFrame, NSView inView)
{
colorize?.Begin(cellFrame, inView);
base.DrawWithFrame(cellFrame, inView);
}
}

protected override bool DefaultUseAlignmentFrame => true;
Expand Down Expand Up @@ -276,19 +295,6 @@ public int SelectedIndex
}
}

public override Color BackgroundColor
{
get { return ((NSComboBoxCell)Control.Cell).BackgroundColor.ToEto(); }
set
{
if (value != BackgroundColor)
{
((NSComboBoxCell)Control.Cell).BackgroundColor = value.ToNSUI();
Control.SetNeedsDisplay();
}
}
}

public Color TextColor
{
get { return ((NSComboBoxCell)Control.Cell).TextColor.ToEto(); }
Expand All @@ -306,7 +312,7 @@ public string Text
{
get { return Control.StringValue; }
set
{
{
if (Text != value)
{
Control.StringValue = value ?? string.Empty;
Expand All @@ -327,7 +333,7 @@ public bool ReadOnly
{
get { return !Control.Editable; }
set
{
{
Control.Editable = !value;
if (Control.Window != null)
Control.Window.MakeFirstResponder(null); // allows editing if currently focussed, so remove focus
Expand Down
27 changes: 15 additions & 12 deletions src/Eto.Mac/Forms/Controls/DateTimePickerHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,25 @@ public class EtoDatePicker : NSDatePicker, IMacControl
{
public override void DrawRect(CGRect dirtyRect)
{
if (Handler.curValue != null)
var h = Handler;
if (h == null)
{
if (Cell.BackgroundStyle == NSBackgroundStyle.Dark && Cell.TextColor == NSColor.ControlText)
{
Cell.TextColor = NSColor.AlternateSelectedControlText;
base.DrawRect(dirtyRect);
Cell.TextColor = NSColor.ControlText;
}
else
base.DrawRect(dirtyRect);
base.DrawRect(dirtyRect);
return;
}

if (h.curValue != null)
{
base.DrawRect(dirtyRect);
}
else
{
// paint with no elements visible
var old = DatePickerElements;
DatePickerElements = 0;
// use transparent color so sizing is still correct.
var old = TextColor;
TextColor = NSColor.Clear;
base.DrawRect(dirtyRect);
DatePickerElements = old;
TextColor = old;
}
}

Expand Down Expand Up @@ -201,10 +202,12 @@ public Color TextColor

protected override void SetBackgroundColor(Color? color)
{
// base.SetBackgroundColor(color);
if (color != null)
{
Control.BackgroundColor = color.Value.ToNSUI();
Control.DrawsBackground = color.Value.A > 0;
Control.WantsLayer = color.Value.A < 1;
}
else
{
Expand Down
15 changes: 1 addition & 14 deletions src/Eto.Mac/Forms/Controls/DropDownHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public override void MenuDidClose(NSMenu menu)

CollectionHandler collection;

public class EtoPopUpButtonCell : NSPopUpButtonCell
public class EtoPopUpButtonCell : NSPopUpButtonCell, IColorizeCell
{
NSDictionary textAttributes;
Color? textColor;
Expand Down Expand Up @@ -301,19 +301,6 @@ public int SelectedIndex
}
}

public override Color BackgroundColor
{
get { return ((EtoPopUpButtonCell)Control.Cell).Color ?? Colors.Transparent; }
set
{
if (value != BackgroundColor)
{
((EtoPopUpButtonCell)Control.Cell).Color = value;
Control.SetNeedsDisplay();
}
}
}

public Color TextColor
{
get { return ((EtoPopUpButtonCell)Control.Cell).TextColor ?? NSColor.ControlText.ToEto(); }
Expand Down
1 change: 1 addition & 0 deletions src/Eto.Mac/Forms/Controls/ListBoxHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ protected override void Initialize()
Control.Delegate = new EtoDelegate { Handler = this };

scroll = new EtoScrollView { Handler = this };
scroll.DrawsBackground = false;
scroll.AutoresizesSubviews = true;
scroll.DocumentView = Control;
scroll.HasVerticalScroller = true;
Expand Down
5 changes: 4 additions & 1 deletion src/Eto.Mac/Forms/Controls/MacControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public abstract class MacControl<TControl, TWidget, TCallback> : MacView<TContro

protected override bool ControlEnabled
{
get => Control.Enabled;
get => Control.Enabled;
set => Control.Enabled = value;
}

Expand All @@ -50,6 +50,9 @@ public virtual Font Font
};
}
}

protected override IColorizeCell ColorizeCell => Control.Cell as IColorizeCell;

}
}

31 changes: 17 additions & 14 deletions src/Eto.Mac/Forms/Controls/MacText.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,25 @@ public abstract class MacText<TControl, TWidget, TCallback> : MacControl<TContro

public Range<int>? InitialSelection { get; set; }

public override Color BackgroundColor
protected override Color DefaultBackgroundColor => Control.BackgroundColor.ToEto();

protected override bool UseColorizeCellWithAlphaOnly => true;

protected override void SetBackgroundColor(Color? color)
{
get { return Control.BackgroundColor.ToEto(); }
set
base.SetBackgroundColor(color);
var c = color ?? Colors.Transparent;
Control.BackgroundColor = c.ToNSUI();
Control.DrawsBackground = c.A > 0;
Control.WantsLayer = c.A < 1;
if (Widget.Loaded && HasFocus)
{
var color = value.ToNSUI();
Control.BackgroundColor = color;
Control.DrawsBackground = value.A > 0;
if (Widget.Loaded && HasFocus)
var editor = Control.CurrentEditor;
if (editor != null)
{
var editor = Control.CurrentEditor;
if (editor != null)
{
editor.BackgroundColor = color;
editor.DrawsBackground = value.A > 0;
}
var nscolor = c.ToNSUI();
editor.BackgroundColor = nscolor;
editor.DrawsBackground = c.A > 0;
}
}
}
Expand Down Expand Up @@ -102,7 +105,7 @@ public virtual Color TextColor
get { return Control.TextColor.ToEto(); }
set { Control.TextColor = value.ToNSUI(); }
}

public int CaretIndex
{
get { return InitialSelection?.Start ?? (int?)Control.CurrentEditor?.SelectedRange.Location ?? LastSelection?.Start ?? 0; }
Expand Down
Loading