Worked on Mac enhancements.
This commit is contained in:
Родитель
c75c774f06
Коммит
d4a24bff58
|
@ -0,0 +1,17 @@
|
|||
using CoreGraphics;
|
||||
|
||||
namespace HotUI.Mac
|
||||
{
|
||||
public static class CoreGraphicsExtensions
|
||||
{
|
||||
public static Size ToHotUISize(this CGSize size)
|
||||
{
|
||||
return new Size((float)size.Width, (float)size.Height);
|
||||
}
|
||||
|
||||
public static CGSize ToCGSize(this Size size)
|
||||
{
|
||||
return new CGSize(size.Width, size.Height);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace HotUI.Mac.Extensions
|
||||
{
|
||||
public static partial class MacExtensions
|
||||
public static class MacExtensions
|
||||
{
|
||||
static MacExtensions()
|
||||
{
|
||||
|
@ -11,11 +11,11 @@ namespace HotUI.Mac.Extensions
|
|||
|
||||
public static NSViewController ToViewController (this View view, bool allowNav = true)
|
||||
{
|
||||
|
||||
var handler = view.ToINSView ();
|
||||
|
||||
var vc = new HotUIViewController {
|
||||
CurrentView = view.ToINSView (),
|
||||
var vc = new HotUIViewController
|
||||
{
|
||||
CurrentView = view,
|
||||
};
|
||||
if (view.BuiltView is NavigationView nav && allowNav) {
|
||||
var navController = new NSNavigationController ();
|
||||
|
@ -47,5 +47,33 @@ namespace HotUI.Mac.Extensions
|
|||
return handler as INSView;
|
||||
}
|
||||
|
||||
}
|
||||
public static Font ToFont(this NSFont font)
|
||||
{
|
||||
if (font == null)
|
||||
return Font.System(12);
|
||||
|
||||
// todo: implement support for attributes other than name and size.
|
||||
return font.FamilyName == Device.FontService.SystemFontName
|
||||
? Font.System((float)font.PointSize)
|
||||
: Font.Custom(font.FamilyName, (float)font.PointSize);
|
||||
}
|
||||
|
||||
public static NSFont ToUIFont(this Font font)
|
||||
{
|
||||
if (font == null)
|
||||
return NSFont.SystemFontOfSize(12);
|
||||
|
||||
var attributes = font.Attributes;
|
||||
if (attributes.Name == Device.FontService.SystemFontName)
|
||||
{
|
||||
var weight = (int)attributes.Weight;
|
||||
if (weight > (int)Weight.Regular)
|
||||
return NSFont.BoldSystemFontOfSize(attributes.Size);
|
||||
|
||||
return NSFont.SystemFontOfSize(attributes.Size);
|
||||
}
|
||||
|
||||
return NSFont.FromFontName(attributes.Name, attributes.Size);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
using AppKit;
|
||||
|
||||
namespace HotUI.Mac.Extensions
|
||||
{
|
||||
public static class NSViewExtensions
|
||||
{
|
||||
public static void InsertSubview(this NSView parent, NSView childView, int index)
|
||||
{
|
||||
if (parent == null || childView == null)
|
||||
return;
|
||||
|
||||
var otherView = parent.Subviews[index];
|
||||
parent.AddSubview(childView, NSWindowOrderingMode.Below, otherView);
|
||||
}
|
||||
|
||||
public static void SetNeedsLayout(this NSView parent)
|
||||
{
|
||||
if (parent == null)
|
||||
return;
|
||||
|
||||
parent.NeedsLayout = true;
|
||||
}
|
||||
|
||||
public static Color ToColor(this NSColor color)
|
||||
{
|
||||
if (color == null)
|
||||
return null;
|
||||
|
||||
color = color.UsingColorSpace(NSColorSpace.DeviceRGB);
|
||||
return new Color((float)color.RedComponent, (float)color.GreenComponent, (float)color.BlueComponent, (float)color.AlphaComponent);
|
||||
}
|
||||
|
||||
public static NSColor ToNSColor(this Color color)
|
||||
{
|
||||
if (color == null)
|
||||
return null;
|
||||
|
||||
return NSColor.FromDeviceRgba(color.Red, color.Green, color.Blue, color.Alpha);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
using System.Collections.Generic;
|
||||
using CoreGraphics;
|
||||
using HotUI.Layout;
|
||||
using AppKit;
|
||||
using HotUI.Mac.Extensions;
|
||||
|
||||
namespace HotUI.Mac
|
||||
{
|
||||
public class AbstractLayoutHandler : NSView, INSView, ILayoutHandler<NSView>
|
||||
{
|
||||
private readonly ILayoutManager<NSView> _layoutManager;
|
||||
private AbstractLayout _view;
|
||||
private Size _measured;
|
||||
private bool _measurementValid;
|
||||
|
||||
public AbstractLayout LayoutView => _view;
|
||||
|
||||
public override bool IsFlipped => true;
|
||||
|
||||
protected AbstractLayoutHandler(CGRect rect, ILayoutManager<NSView> layoutManager) : base(rect)
|
||||
{
|
||||
_layoutManager = layoutManager;
|
||||
InitializeDefaults();
|
||||
}
|
||||
|
||||
protected AbstractLayoutHandler(ILayoutManager<NSView> layoutManager)
|
||||
{
|
||||
_layoutManager = layoutManager;
|
||||
InitializeDefaults();
|
||||
}
|
||||
|
||||
public Size Measure(NSView view, Size available)
|
||||
{
|
||||
CGSize size;
|
||||
if (view is AbstractLayoutHandler handler)
|
||||
{
|
||||
size = handler.SizeThatFits(available.ToCGSize());
|
||||
}
|
||||
else
|
||||
{
|
||||
size = view.IntrinsicContentSize;
|
||||
if (size.Width == 0 || size.Height == 0)
|
||||
size = view.Bounds.Size;
|
||||
}
|
||||
|
||||
return size.ToHotUISize();
|
||||
}
|
||||
|
||||
public Size GetSize(NSView view)
|
||||
{
|
||||
var size = view.Bounds.Size;
|
||||
if (size.Width == 0 || size.Height == 0)
|
||||
size = view.IntrinsicContentSize;
|
||||
|
||||
return size.ToHotUISize();
|
||||
}
|
||||
|
||||
public void SetFrame(NSView view, float x, float y, float width, float height)
|
||||
{
|
||||
view.Frame = new CGRect(x, y, width, height);
|
||||
}
|
||||
|
||||
public void SetSize(NSView view, float width, float height)
|
||||
{
|
||||
if ((Equals(width, (float)Frame.Width) && Equals(height, (float)Frame.Height)))
|
||||
return;
|
||||
|
||||
view.Frame = new CGRect(Frame.X, Frame.Y, width, height);
|
||||
}
|
||||
|
||||
public IEnumerable<NSView> GetSubviews()
|
||||
{
|
||||
return Subviews;
|
||||
}
|
||||
|
||||
public NSView View => this;
|
||||
|
||||
public void SetView(View view)
|
||||
{
|
||||
_view = view as AbstractLayout;
|
||||
if (_view != null)
|
||||
{
|
||||
_view.ChildrenChanged += HandleChildrenChanged;
|
||||
_view.ChildrenAdded += HandleChildrenAdded;
|
||||
_view.ChildrenRemoved += ViewOnChildrenRemoved;
|
||||
|
||||
foreach (var subView in _view)
|
||||
{
|
||||
var nativeView = subView.ToView() ?? new NSView();
|
||||
AddSubview(nativeView);
|
||||
}
|
||||
|
||||
SetNeedsLayout();
|
||||
_measurementValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove(View view)
|
||||
{
|
||||
foreach (var subview in Subviews)
|
||||
subview.RemoveFromSuperview();
|
||||
|
||||
if (view != null)
|
||||
{
|
||||
_view.ChildrenChanged -= HandleChildrenChanged;
|
||||
_view.ChildrenAdded -= HandleChildrenAdded;
|
||||
_view.ChildrenRemoved -= ViewOnChildrenRemoved;
|
||||
_view = null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void UpdateValue(string property, object value)
|
||||
{
|
||||
}
|
||||
|
||||
private void InitializeDefaults()
|
||||
{
|
||||
TranslatesAutoresizingMaskIntoConstraints = false;
|
||||
}
|
||||
|
||||
private void HandleChildrenAdded(object sender, LayoutEventArgs e)
|
||||
{
|
||||
for (var i = 0; i < e.Count; i++)
|
||||
{
|
||||
var index = e.Start + i;
|
||||
var view = _view[index];
|
||||
var nativeView = view.ToView() ?? new NSView();
|
||||
this.InsertSubview(nativeView, index);
|
||||
}
|
||||
|
||||
SetNeedsLayout();
|
||||
_measurementValid = false;
|
||||
}
|
||||
|
||||
private void ViewOnChildrenRemoved(object sender, LayoutEventArgs e)
|
||||
{
|
||||
for (var i = 0; i < e.Count; i++)
|
||||
{
|
||||
var index = e.Start + i;
|
||||
var nativeView = Subviews[index];
|
||||
nativeView.RemoveFromSuperview();
|
||||
}
|
||||
|
||||
SetNeedsLayout();
|
||||
_measurementValid = false;
|
||||
}
|
||||
|
||||
private void HandleChildrenChanged(object sender, LayoutEventArgs e)
|
||||
{
|
||||
for (var i = 0; i < e.Count; i++)
|
||||
{
|
||||
var index = e.Start + i;
|
||||
var oldNativeView = Subviews[index];
|
||||
oldNativeView.RemoveFromSuperview();
|
||||
|
||||
var view = _view[index];
|
||||
var newNativeView = view.ToView() ?? new NSView();
|
||||
this.InsertSubview(newNativeView, index);
|
||||
}
|
||||
|
||||
SetNeedsLayout();
|
||||
_measurementValid = false;
|
||||
}
|
||||
|
||||
private void SetNeedsLayout()
|
||||
{
|
||||
NeedsLayout = true;
|
||||
}
|
||||
|
||||
public CGSize SizeThatFits(CGSize size)
|
||||
{
|
||||
_measured = _layoutManager.Measure(this, this, _view, size.ToHotUISize());
|
||||
_measurementValid = true;
|
||||
return _measured.ToCGSize();
|
||||
}
|
||||
|
||||
public void SizeToFit()
|
||||
{
|
||||
_measured = _layoutManager.Measure(this, this, _view, Superview?.Bounds.Size.ToHotUISize() ?? NSScreen.MainScreen.Frame.Size.ToHotUISize());
|
||||
_measurementValid = true;
|
||||
base.Frame = new CGRect(new CGPoint(0, 0), _measured.ToCGSize());
|
||||
}
|
||||
|
||||
public override CGSize IntrinsicContentSize => _measured.ToCGSize();
|
||||
|
||||
|
||||
public override CGRect Frame
|
||||
{
|
||||
get => base.Frame;
|
||||
set
|
||||
{
|
||||
base.Frame = value;
|
||||
Layout();
|
||||
NeedsLayout = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ViewDidMoveToSuperview()
|
||||
{
|
||||
if (NeedsLayout)
|
||||
{
|
||||
Layout();
|
||||
NeedsLayout = false;
|
||||
}
|
||||
|
||||
base.ViewDidMoveToSuperview();
|
||||
}
|
||||
|
||||
public override void Layout()
|
||||
{
|
||||
if (Superview == null || Bounds.Size.IsEmpty)
|
||||
return;
|
||||
|
||||
var available = Bounds.Size.ToHotUISize();
|
||||
if (!_measurementValid)
|
||||
{
|
||||
_measured = _layoutManager.Measure(this, this, _view, available);
|
||||
_measurementValid = true;
|
||||
}
|
||||
|
||||
_layoutManager.Layout(this, this, _view, _measured);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,6 +13,11 @@ namespace HotUI.Mac.Handlers
|
|||
|
||||
public ButtonHandler()
|
||||
{
|
||||
Cell.ControlSize = NSControlSize.Regular;
|
||||
BezelStyle = NSBezelStyle.Rounded;
|
||||
SetButtonType(NSButtonType.MomentaryPushIn);
|
||||
Font = NSFont.SystemFontOfSize(NSFont.SystemFontSizeForControlSize(NSControlSize.Regular));
|
||||
|
||||
Activated += HandleTouchUpInside;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
using AppKit;
|
||||
using CoreGraphics;
|
||||
using HotUI.Layout;
|
||||
|
||||
namespace HotUI.Mac.Handlers
|
||||
{
|
||||
public class HStackHandler : AbstractLayoutHandler
|
||||
{
|
||||
public HStackHandler(CGRect rect) : base(rect, new HStackLayoutManager<NSView>())
|
||||
{
|
||||
}
|
||||
|
||||
public HStackHandler() : base(new HStackLayoutManager<NSView>())
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ using Foundation;
|
|||
using HotUI.Mac.Extensions;
|
||||
|
||||
namespace HotUI.Mac {
|
||||
public class ListViewHandler : NSView, INSView, INSTableViewDataSource, INSTableViewDelegate {
|
||||
public class ListViewHandler : NSColorView, INSView, INSTableViewDataSource, INSTableViewDelegate {
|
||||
|
||||
|
||||
NSTableView TableView;
|
||||
|
@ -16,8 +16,8 @@ namespace HotUI.Mac {
|
|||
|
||||
TableView.AddColumn (new NSTableColumn ("ListView"));
|
||||
TableView.HeaderView = null;
|
||||
TableView.UsesAutomaticRowHeights = true;
|
||||
TableView.RowHeight = 100;
|
||||
//TableView.UsesAutomaticRowHeights = true;
|
||||
TableView.RowHeight = 44;
|
||||
TableView.SizeLastColumnToFit ();
|
||||
TableView.WeakDataSource = this;
|
||||
TableView.WeakDelegate = this;
|
||||
|
@ -43,14 +43,16 @@ namespace HotUI.Mac {
|
|||
return;
|
||||
cellIdentifier = listView.GetType ().Name;
|
||||
TableView.ReloadData ();
|
||||
}
|
||||
TableView.SizeLastColumnToFit();
|
||||
}
|
||||
|
||||
public void UpdateValue (string property, object value)
|
||||
public void UpdateValue (string property, object value)
|
||||
{
|
||||
TableView.ReloadData ();
|
||||
}
|
||||
TableView.SizeLastColumnToFit();
|
||||
}
|
||||
|
||||
string cellIdentifier = "viewCell";
|
||||
string cellIdentifier = "viewCell";
|
||||
[Export ("tableView:viewForTableColumn:row:")]
|
||||
public NSView GetViewForItem (NSTableView tableView, NSTableColumn tableColumn, nint row)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
using AppKit;
|
||||
|
||||
// ReSharper disable ClassNeverInstantiated.Global
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
|
||||
namespace HotUI.Mac
|
||||
{
|
||||
public class SpacerHandler : NSColorView, INSView
|
||||
{
|
||||
public static readonly PropertyMapper<Spacer, NSView, NSView> Mapper = new PropertyMapper<Spacer, NSView, NSView>(ViewHandler.Mapper)
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
private Spacer _spacer;
|
||||
|
||||
public NSView View => this;
|
||||
|
||||
public void Remove(View view)
|
||||
{
|
||||
_spacer = null;
|
||||
}
|
||||
|
||||
public void SetView(View view)
|
||||
{
|
||||
_spacer = view as Spacer;
|
||||
Mapper.UpdateProperties(this, _spacer);
|
||||
}
|
||||
|
||||
public void UpdateValue(string property, object value)
|
||||
{
|
||||
Mapper.UpdateProperty(this, _spacer, property);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,13 +7,26 @@ namespace HotUI.Mac.Handlers
|
|||
{
|
||||
public static readonly PropertyMapper<Text, NSView, NSTextField> Mapper = new PropertyMapper<Text, NSView, NSTextField>(ViewHandler.Mapper)
|
||||
{
|
||||
[nameof(Text.Value)] = MapValueProperty
|
||||
[nameof(Text.Value)] = MapValueProperty,
|
||||
[EnvironmentKeys.Fonts.Font] = MapFontProperty,
|
||||
[EnvironmentKeys.Colors.Color] = MapColorProperty,
|
||||
};
|
||||
|
||||
private static Font DefaultFont;
|
||||
private static Color DefaultColor;
|
||||
private static Color DefaultBackgroundColor;
|
||||
|
||||
public NSView View => this;
|
||||
|
||||
public TextHandler()
|
||||
{
|
||||
if (DefaultColor == null)
|
||||
{
|
||||
DefaultFont = Font.ToFont();
|
||||
DefaultColor = TextColor.ToColor();
|
||||
DefaultBackgroundColor = BackgroundColor.ToColor();
|
||||
}
|
||||
|
||||
Editable = false;
|
||||
Bezeled = false;
|
||||
DrawsBackground = false;
|
||||
|
@ -43,27 +56,23 @@ namespace HotUI.Mac.Handlers
|
|||
nativeView.SizeToFit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static partial class ControlExtensions
|
||||
{
|
||||
public static void UpdateLabelProperties(this NSTextField view, Text hView)
|
||||
public static bool MapFontProperty(NSTextField nativeView, Text virtualView)
|
||||
{
|
||||
view.UpdateLabelProperty(nameof(Text.Value), hView?.Value);
|
||||
view.UpdateBaseProperties(hView);
|
||||
var font = virtualView.GetFont(DefaultFont);
|
||||
nativeView.Font = font.ToUIFont();
|
||||
nativeView.SizeToFit();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool UpdateLabelProperty(this NSTextField view, string property, object value)
|
||||
public static bool MapColorProperty(NSTextField nativeView, Text virtualView)
|
||||
{
|
||||
switch (property)
|
||||
{
|
||||
case nameof(Text.Value):
|
||||
view.StringValue = (string) value;
|
||||
view.SizeToFit();
|
||||
return true;
|
||||
}
|
||||
var color = virtualView.GetColor(DefaultColor);
|
||||
var nativeColor = nativeView.TextColor.ToColor();
|
||||
if (!color.Equals(nativeColor))
|
||||
nativeView.TextColor = color.ToNSColor();
|
||||
|
||||
return view.UpdateBaseProperty(property, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,91 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AppKit;
|
||||
using AppKit;
|
||||
using CoreGraphics;
|
||||
using HotUI.Mac.Controls;
|
||||
using HotUI.Mac.Extensions;
|
||||
using HotUI.Layout;
|
||||
|
||||
namespace HotUI.Mac.Handlers
|
||||
{
|
||||
public class VStackHandler : StackView, INSView
|
||||
public class VStackHandler : AbstractLayoutHandler
|
||||
{
|
||||
public VStackHandler()
|
||||
{
|
||||
Frame = new CGRect(0, 0, 800, 600);
|
||||
Console.WriteLine("New stack handler created");
|
||||
}
|
||||
|
||||
public NSView View => this;
|
||||
|
||||
public void Remove(View view)
|
||||
{
|
||||
if (_stack != null)
|
||||
{
|
||||
_stack.ChildrenChanged -= Stack_ChildrenChanged;
|
||||
_stack = null;
|
||||
}
|
||||
}
|
||||
|
||||
VStack _stack;
|
||||
|
||||
public void SetView(View view)
|
||||
{
|
||||
_stack = view as VStack;
|
||||
UpdateChildren(_stack);
|
||||
_stack.ChildrenChanged += Stack_ChildrenChanged;
|
||||
}
|
||||
|
||||
private void Stack_ChildrenChanged(object sender, EventArgs e)
|
||||
{
|
||||
UpdateChildren(_stack);
|
||||
}
|
||||
|
||||
public void UpdateValue(string property, object value)
|
||||
public VStackHandler(CGRect rect) : base(rect, new VStackLayoutManager<NSView>())
|
||||
{
|
||||
}
|
||||
|
||||
List<NSView> views = new List<NSView>();
|
||||
|
||||
protected void UpdateChildren(VStack stack)
|
||||
public VStackHandler() : base(new VStackLayoutManager<NSView>())
|
||||
{
|
||||
var children = stack.GetChildren();
|
||||
if (views.Count == children.Count)
|
||||
{
|
||||
bool areSame = false;
|
||||
for (var i = 0; i < views.Count; i++)
|
||||
{
|
||||
var v = views[i];
|
||||
var c = children[i].ToView();
|
||||
areSame = c == v;
|
||||
if (!areSame)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (areSame)
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var v in views)
|
||||
v.RemoveFromSuperview();
|
||||
views.Clear();
|
||||
|
||||
foreach (var child in children)
|
||||
{
|
||||
var cview = child.ToView();
|
||||
cview.TranslatesAutoresizingMaskIntoConstraints = false;
|
||||
|
||||
views.Add(cview);
|
||||
|
||||
// todo: fixme, this is hack to get the controls to show up
|
||||
if (cview.Bounds.Width <= 0 && cview.Bounds.Height <= 0)
|
||||
cview.SetFrameSize(new CGSize(200, 24));
|
||||
|
||||
AddSubview(cview);
|
||||
}
|
||||
|
||||
LayoutSubviews();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,39 +9,66 @@ namespace HotUI.Mac
|
|||
{
|
||||
public static readonly PropertyMapper<View, NSView, NSView> Mapper = new PropertyMapper<View, NSView, NSView>()
|
||||
{
|
||||
[nameof(EnvironmentKeys.Colors.BackgroundColor)] = MapBackgroundColorProperty
|
||||
};
|
||||
|
||||
private View _view;
|
||||
private NSView _body;
|
||||
|
||||
public Action ViewChanged { get; set; }
|
||||
|
||||
public NSView View {
|
||||
get {
|
||||
var iView = currentView?.ToINSView ();
|
||||
if(iView?.GetType() == typeof(ViewHandler) && currentView?.Body == null) {
|
||||
//This is recusrive!!!
|
||||
Debug.WriteLine ($"There is no View Handler for {currentView.GetType()}");
|
||||
return new NSView ();
|
||||
}
|
||||
public NSView View => _body;
|
||||
|
||||
return iView?.View ?? new NSView ();
|
||||
}
|
||||
}
|
||||
public void Remove(View view)
|
||||
{
|
||||
_view = null;
|
||||
_body = null;
|
||||
}
|
||||
|
||||
View currentView;
|
||||
public void Remove (View view)
|
||||
{
|
||||
currentView = null;
|
||||
}
|
||||
public void SetView(View view)
|
||||
{
|
||||
_view = view;
|
||||
SetBody();
|
||||
Mapper.UpdateProperties(_body, _view);
|
||||
ViewChanged?.Invoke();
|
||||
}
|
||||
|
||||
public void SetView (View view)
|
||||
{
|
||||
currentView = view;
|
||||
View?.UpdateProperties (view);
|
||||
ViewChanged?.Invoke ();
|
||||
}
|
||||
public void UpdateValue(string property, object value)
|
||||
{
|
||||
Mapper.UpdateProperty(_body, _view, property);
|
||||
}
|
||||
|
||||
public void UpdateValue (string property, object value)
|
||||
{
|
||||
View.UpdateBaseProperty (property, value);
|
||||
}
|
||||
public bool SetBody()
|
||||
{
|
||||
var uiElement = _view?.ToINSView();
|
||||
if (uiElement?.GetType() == typeof(ViewHandler) && _view.Body == null)
|
||||
{
|
||||
// this is recursive.
|
||||
Debug.WriteLine($"There is no ViewHandler for {_view.GetType()}");
|
||||
return true;
|
||||
}
|
||||
|
||||
_body = uiElement?.View ?? new NSColorView();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool MapBackgroundColorProperty(NSView nativeView, View virtualView)
|
||||
{
|
||||
var color = virtualView.GetBackgroundColor();
|
||||
if (color != null)
|
||||
{
|
||||
if (nativeView is NSColorView colorView)
|
||||
{
|
||||
colorView.BackgroundColor = color.ToNSColor();
|
||||
}
|
||||
else if (nativeView is NSTextField textField)
|
||||
{
|
||||
textField.BackgroundColor = color.ToNSColor();
|
||||
textField.DrawsBackground = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,10 @@
|
|||
<Reference Include="netstandard" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Extensions\CoreGraphicsExtensions.cs" />
|
||||
<Compile Include="Extensions\NSViewExtensions.cs" />
|
||||
<Compile Include="Handlers\AbstractLayoutHandler.cs" />
|
||||
<Compile Include="HotUIView.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Extensions\ControlExtensions.cs" />
|
||||
<Compile Include="Extensions\MacExtensions.cs" />
|
||||
|
@ -80,6 +84,9 @@
|
|||
<Compile Include="Controls\NSColorView.cs" />
|
||||
<Compile Include="Handlers\ContentViewHandler.cs" />
|
||||
<Compile Include="Handlers\ListViewHandler.cs" />
|
||||
<Compile Include="Handlers\HStackHandler.cs" />
|
||||
<Compile Include="Handlers\SpacerHandler.cs" />
|
||||
<Compile Include="Services\MacFontService.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\HotUI\HotUI.csproj">
|
||||
|
@ -89,6 +96,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Controls\" />
|
||||
<Folder Include="Services\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Mac\Xamarin.Mac.CSharp.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,129 @@
|
|||
using CoreGraphics;
|
||||
using AppKit;
|
||||
using HotUI.Mac.Extensions;
|
||||
|
||||
namespace HotUI.Mac
|
||||
{
|
||||
public class HotUIView : NSColorView
|
||||
{
|
||||
private View _virtualView;
|
||||
private INSView _handler;
|
||||
private NSView _nativeView;
|
||||
|
||||
public HotUIView()
|
||||
{
|
||||
TranslatesAutoresizingMaskIntoConstraints = false;
|
||||
AutoresizesSubviews = true;
|
||||
AutoresizingMask = NSViewResizingMask.HeightSizable | NSViewResizingMask.WidthSizable;
|
||||
}
|
||||
|
||||
public HotUIView(CGRect rect) : base(rect)
|
||||
{
|
||||
TranslatesAutoresizingMaskIntoConstraints = false;
|
||||
AutoresizesSubviews = true;
|
||||
AutoresizingMask = NSViewResizingMask.HeightSizable | NSViewResizingMask.WidthSizable;
|
||||
}
|
||||
|
||||
public View CurrentView
|
||||
{
|
||||
get => _virtualView;
|
||||
set
|
||||
{
|
||||
if (value == _virtualView)
|
||||
return;
|
||||
|
||||
_virtualView = value;
|
||||
_handler = _virtualView.ToINSView();
|
||||
if (_handler is ViewHandler viewHandler)
|
||||
viewHandler.ViewChanged = HandleViewChanged;
|
||||
|
||||
HandleViewChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HandleViewChanged()
|
||||
{
|
||||
if (_virtualView == null)
|
||||
return;
|
||||
|
||||
var newNativeView = _handler?.View;
|
||||
if (newNativeView == _nativeView)
|
||||
return;
|
||||
|
||||
_nativeView?.RemoveFromSuperview();
|
||||
_nativeView = newNativeView;
|
||||
|
||||
if (newNativeView != null)
|
||||
{
|
||||
AddSubview(newNativeView);
|
||||
Layout();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetNeedsLayout()
|
||||
{
|
||||
NeedsLayout = true;
|
||||
}
|
||||
|
||||
public override CGRect Frame
|
||||
{
|
||||
get => base.Frame;
|
||||
set
|
||||
{
|
||||
base.Frame = value;
|
||||
Layout();
|
||||
NeedsLayout = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ViewDidMoveToSuperview()
|
||||
{
|
||||
if (NeedsLayout)
|
||||
{
|
||||
Layout();
|
||||
NeedsLayout = false;
|
||||
}
|
||||
|
||||
base.ViewDidMoveToSuperview();
|
||||
}
|
||||
|
||||
public override void Layout()
|
||||
{
|
||||
if (Bounds.IsEmpty || _nativeView == null)
|
||||
return;
|
||||
|
||||
if (_nativeView is NSScrollView sv)
|
||||
{
|
||||
_nativeView.Frame = Bounds;
|
||||
}
|
||||
else
|
||||
{
|
||||
var bounds = Bounds;
|
||||
|
||||
var padding = _virtualView.GetPadding();
|
||||
if (!padding.IsEmpty)
|
||||
{
|
||||
bounds.X += padding.Left;
|
||||
bounds.Y += padding.Top;
|
||||
bounds.Width -= padding.HorizontalThickness;
|
||||
bounds.Height -= padding.VerticalThickness;
|
||||
}
|
||||
|
||||
if (_nativeView is NSTableView || _nativeView is ListViewHandler)
|
||||
_nativeView.Frame = bounds;
|
||||
else
|
||||
{
|
||||
CGSize sizeThatFits;
|
||||
if (_nativeView is AbstractLayoutHandler layout)
|
||||
sizeThatFits = layout.SizeThatFits(bounds.Size);
|
||||
else
|
||||
sizeThatFits = bounds.Size;
|
||||
var x = ((bounds.Width - sizeThatFits.Width) / 2) + padding.Left;
|
||||
var y = ((bounds.Height - sizeThatFits.Height) / 2) + padding.Top;
|
||||
_nativeView.Frame = new CGRect(x, y, sizeThatFits.Width, sizeThatFits.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,45 +2,36 @@
|
|||
using AppKit;
|
||||
using HotUI.Mac.Extensions;
|
||||
|
||||
namespace HotUI.Mac {
|
||||
public class HotUIViewController : NSViewController {
|
||||
namespace HotUI.Mac
|
||||
{
|
||||
public class HotUIViewController : NSViewController
|
||||
{
|
||||
private HotUIView _containerView;
|
||||
|
||||
public HotUIViewController()
|
||||
{
|
||||
View = new NSView ();
|
||||
}
|
||||
INSView currentView;
|
||||
public INSView CurrentView {
|
||||
get => currentView;
|
||||
set {
|
||||
if (value == currentView)
|
||||
return;
|
||||
currentView = value;
|
||||
if (currentView is ViewHandler vh) {
|
||||
vh.ViewChanged = SetView;
|
||||
}
|
||||
public HotUIViewController()
|
||||
{
|
||||
}
|
||||
|
||||
public View CurrentView
|
||||
{
|
||||
get => ContainerView.CurrentView;
|
||||
set => ContainerView.CurrentView = value;
|
||||
}
|
||||
|
||||
SetView ();
|
||||
}
|
||||
}
|
||||
public override void LoadView()
|
||||
{
|
||||
View = ContainerView;
|
||||
}
|
||||
|
||||
private HotUIView ContainerView
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_containerView == null)
|
||||
_containerView = new HotUIView(NSScreen.MainScreen.Frame);
|
||||
|
||||
NSView currentlyShownView;
|
||||
void SetView ()
|
||||
{
|
||||
var view = CurrentView?.View;
|
||||
if (view == currentlyShownView)
|
||||
return;
|
||||
currentlyShownView?.RemoveFromSuperview ();
|
||||
currentlyShownView = view;
|
||||
if (view == null)
|
||||
return;
|
||||
View.AddSubview(view);
|
||||
}
|
||||
public override void ViewDidLayout ()
|
||||
{
|
||||
base.ViewDidLayout ();
|
||||
if (currentlyShownView != null)
|
||||
currentlyShownView.Frame = View.Bounds;
|
||||
}
|
||||
}
|
||||
}
|
||||
return _containerView;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
using HotUI.Services;
|
||||
using AppKit;
|
||||
|
||||
namespace HotUI.Mac.Services
|
||||
{
|
||||
public class MacFontService : IFontService
|
||||
{
|
||||
private string _systemFontName;
|
||||
private string _monospacedFontName;
|
||||
private string _roundedFontName;
|
||||
private string _serifFontName;
|
||||
|
||||
public string SystemFontName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_systemFontName == null)
|
||||
{
|
||||
var font = NSFont.SystemFontOfSize(12);
|
||||
_systemFontName = font.FamilyName;
|
||||
font.Dispose();
|
||||
}
|
||||
|
||||
return _systemFontName;
|
||||
}
|
||||
}
|
||||
|
||||
public string MonospacedFontName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_monospacedFontName == null)
|
||||
{
|
||||
var font = NSFont.MonospacedDigitSystemFontOfSize(12, (int)Weight.Regular);
|
||||
_monospacedFontName = font.FamilyName;
|
||||
font.Dispose();
|
||||
}
|
||||
|
||||
return _monospacedFontName;
|
||||
}
|
||||
}
|
||||
|
||||
public string RoundedFontName
|
||||
{
|
||||
get
|
||||
{
|
||||
// todo: figure out what this should be. For now, just use the system font.
|
||||
if (_roundedFontName == null)
|
||||
{
|
||||
var font = NSFont.SystemFontOfSize(12);
|
||||
_roundedFontName = font.FamilyName;
|
||||
font.Dispose();
|
||||
}
|
||||
|
||||
return _roundedFontName;
|
||||
}
|
||||
}
|
||||
|
||||
public string SerifFontName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_serifFontName == null)
|
||||
{
|
||||
// todo: figure out what this should be. For now, just use times new roman font.
|
||||
var font = NSFont.FromFontName("TimesNewRoman", 12);
|
||||
_serifFontName = font.FamilyName;
|
||||
font.Dispose();
|
||||
}
|
||||
|
||||
return _serifFontName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using Foundation;
|
||||
using HotUI.Mac.Handlers;
|
||||
using HotUI.Mac.Services;
|
||||
|
||||
namespace HotUI.Mac
|
||||
{
|
||||
|
@ -18,6 +19,7 @@ namespace HotUI.Mac
|
|||
Registrar.Handlers.Register<TextField, TextFieldHandler>();
|
||||
Registrar.Handlers.Register<Text, TextHandler>();
|
||||
Registrar.Handlers.Register<VStack, VStackHandler>();
|
||||
Registrar.Handlers.Register<HStack, HStackHandler>();
|
||||
//Registrar.Handlers.Register<WebView, WebViewHandler> ();
|
||||
Registrar.Handlers.Register<ScrollView, ScrollViewHandler>();
|
||||
Registrar.Handlers.Register<Image, ImageHandler> ();
|
||||
|
@ -26,6 +28,7 @@ namespace HotUI.Mac
|
|||
Registrar.Handlers.Register<ListView, ListViewHandler> ();
|
||||
|
||||
Device.PerformInvokeOnMainThread = invoker.BeginInvokeOnMainThread;
|
||||
}
|
||||
Device.FontService = new MacFontService();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using UIKit;
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
|
|
|
@ -56,19 +56,7 @@ namespace HotUI.iOS
|
|||
|
||||
SetNeedsLayout();
|
||||
}
|
||||
|
||||
public override CGRect Frame
|
||||
{
|
||||
get => base.Frame;
|
||||
set => base.Frame = value;
|
||||
}
|
||||
|
||||
public override CGRect Bounds
|
||||
{
|
||||
get => base.Bounds;
|
||||
set { /* do nothing */ }
|
||||
}
|
||||
|
||||
|
||||
public override void LayoutSubviews()
|
||||
{
|
||||
if (Bounds.IsEmpty || _nativeView == null)
|
||||
|
|
Загрузка…
Ссылка в новой задаче