[GTK] Fix transparent background in visual elements (#3744)

This commit is contained in:
Andoni Morales Alastruey 2018-10-05 03:24:22 +02:00 коммит произвёл Samantha Houts
Родитель ba226e26fc
Коммит 717db0dba1
24 изменённых файлов: 185 добавлений и 477 удалений

Просмотреть файл

@ -1,160 +1,21 @@
using Cairo; using Cairo;
using Gdk;
using Gtk;
using System; using System;
namespace Xamarin.Forms.Platform.GTK.Controls namespace Xamarin.Forms.Platform.GTK.Controls
{ {
public class ActivityIndicator : EventBox public class ActivityIndicator : GtkFormsContainer
{ {
private const int DefaultHeight = 48; private const int DefaultHeight = 48;
private const int DefaultWidth = 48; private const int DefaultWidth = 48;
private const int Lines = 8;
private ActivityIndicatorDrawingArea _activityIndicator; private bool _running;
private int _current;
private Color _color;
public ActivityIndicator() public ActivityIndicator()
{ {
HeightRequest = DefaultHeight; HeightRequest = DefaultHeight;
WidthRequest = DefaultWidth; WidthRequest = DefaultWidth;
// Custom control created with Cairo.
_activityIndicator = new ActivityIndicatorDrawingArea
{
Height = HeightRequest,
Width = WidthRequest
};
_activityIndicator.SetFlag(WidgetFlags.NoWindow);
Add(_activityIndicator);
}
public void Start()
{
if (_activityIndicator != null)
{
_activityIndicator.Start();
}
}
public void Stop()
{
if (_activityIndicator != null)
{
_activityIndicator.Stop();
}
}
public void UpdateBackgroundColor(Gdk.Color backgroundColor)
{
if (_activityIndicator != null)
{
_activityIndicator.BackgroundColor = backgroundColor;
_activityIndicator.ModifyBg(StateType.Normal, backgroundColor);
}
}
public void UpdateAlpha(double alpha)
{
if (_activityIndicator != null)
{
_activityIndicator.Alpha = alpha;
}
}
public void UpdateColor(Gdk.Color color)
{
if (_activityIndicator != null)
{
_activityIndicator.Color = color;
}
}
}
public class ActivityIndicatorDrawingArea : DrawingArea
{
private int _height;
private int _width;
private bool _running;
private int _current;
private int _lines;
private Gdk.Color _color;
private Gdk.Color _backgroundColor;
private double _alpha;
public ActivityIndicatorDrawingArea()
{
_height = 48;
_width = 48;
_current = 0;
_lines = 8; // Number of lines in circular form.
_running = false;
QueueResize();
}
public int Height
{
get { return (_height); }
set
{
_height = value;
QueueDraw();
}
}
public int Width
{
get { return (_width); }
set
{
_width = value;
QueueDraw();
}
}
public int Lines
{
get { return (_lines); }
set
{
_lines = value;
QueueDraw();
}
}
public Gdk.Color Color
{
get { return (_color); }
set
{
_color = value;
QueueDraw();
}
}
public Gdk.Color BackgroundColor
{
get { return (_backgroundColor); }
set
{
_backgroundColor = value;
QueueDraw();
}
}
public double Alpha
{
get { return (_alpha); }
set
{
_alpha = value;
QueueDraw();
}
}
public bool IsRunning
{
get { return (_running); }
} }
public void Start() public void Start()
@ -170,29 +31,14 @@ namespace Xamarin.Forms.Platform.GTK.Controls
QueueDraw(); QueueDraw();
} }
protected override bool OnExposeEvent(EventExpose evnt) public void UpdateColor(Color color)
{ {
base.OnExposeEvent(evnt); _color = color;
using (var cr = CairoHelper.Create(GdkWindow))
{
cr.Rectangle(
evnt.Area.X,
evnt.Area.Y,
Height,
Width);
cr.Clip();
Draw(cr);
}
return (true);
} }
private bool ExposeTimeoutHandler() private bool ExposeTimeoutHandler()
{ {
if (_current + 1 > _lines) if (_current + 1 > Lines)
{ {
_current = 0; _current = 0;
} }
@ -204,48 +50,27 @@ namespace Xamarin.Forms.Platform.GTK.Controls
return (_running); return (_running);
} }
private void Draw(Context cr) protected override void Draw(Gdk.Rectangle area, Context cr)
{ {
// Set BackgroundColor
cr.Save();
var cairoBackgroundColor = new Cairo.Color(
(double)BackgroundColor.Red / ushort.MaxValue,
(double)BackgroundColor.Green / ushort.MaxValue,
(double)BackgroundColor.Blue / ushort.MaxValue);
cr.SetSourceRGBA(cairoBackgroundColor.R, cairoBackgroundColor.G, cairoBackgroundColor.B, Alpha);
cr.Paint();
cr.Restore();
// Draw Activity Indicator // Draw Activity Indicator
double radius; double radius;
double half; double half;
double x, y; double x, y;
x = Allocation.X + Width / 2; x = Allocation.Width / 2;
y = Allocation.Y + _height / 2; y = Allocation.Height / 2;
radius = Math.Min( radius = Math.Min(x, y);
Width / 2,
_height / 2);
half = _lines / 2; half = Lines / 2;
for (int i = 0; i < _lines; i++) for (int i = 0; i < Lines; i++)
{ {
double move = (double)((i + _lines - _current) % _lines) / _lines; double move = (double)((i + Lines - _current) % Lines) / Lines;
double inset = 0.5 * radius; double inset = 0.5 * radius;
cr.Save(); cr.Save();
cr.SetSourceRGBA(_color.R, _color.G, _color.B, move);
var cairoColor = new Cairo.Color(
(double)Color.Red / ushort.MaxValue,
(double)Color.Green / ushort.MaxValue,
(double)Color.Blue / ushort.MaxValue);
cr.SetSourceRGBA(cairoColor.R, cairoColor.G, cairoColor.B, move);
cr.LineWidth *= 2; cr.LineWidth *= 2;
cr.MoveTo(move + x + (radius - inset) * Math.Cos(i * Math.PI / half), cr.MoveTo(move + x + (radius - inset) * Math.Cos(i * Math.PI / half),
move + y + (radius - inset) * Math.Sin(i * Math.PI / half)); move + y + (radius - inset) * Math.Sin(i * Math.PI / half));

Просмотреть файл

@ -1,196 +1,63 @@
using Cairo; using Cairo;
using Gdk;
using Gtk;
using System; using System;
using Xamarin.Forms.Platform.GTK.Extensions;
namespace Xamarin.Forms.Platform.GTK.Controls namespace Xamarin.Forms.Platform.GTK.Controls
{ {
public class BoxView : VBox public class BoxView : GtkFormsContainer
{ {
private BoxViewDrawingArea _boxView; private Color _color;
public BoxView()
{
// Custom control created with Cairo. It gives nice possibilities as rounded corners, etc.
_boxView = new BoxViewDrawingArea();
Add(_boxView);
}
public void UpdateColor(Gdk.Color color)
{
if (_boxView != null)
{
_boxView.Color = color;
}
}
public void ResetColor()
{
UpdateColor(Gdk.Color.Zero);
}
public void UpdateBackgroundColor(Gdk.Color color)
{
if (_boxView != null)
{
_boxView.ModifyBg(StateType.Normal, color);
}
}
public void UpdateSize(int height, int width)
{
if (_boxView != null)
{
_boxView.Height = height;
_boxView.Width = width;
}
}
public void UpdateBorderRadius(int topLeftRadius = 5, int topRightRadius = 5, int bottomLeftRadius = 5, int bottomRightRadius = 5)
{
if (_boxView != null)
{
_boxView.TopLeftRadius = topLeftRadius > 0 ? topLeftRadius : 0;
_boxView.TopRightRadius = topRightRadius > 0 ? topRightRadius : 0;
_boxView.BottomLeftRadius = bottomLeftRadius > 0 ? bottomLeftRadius : 0;
_boxView.BottomRightRadius = bottomRightRadius > 0 ? bottomRightRadius : 0;
}
}
}
public class BoxViewDrawingArea : DrawingArea
{
private Context _context;
private EventExpose _event;
private Gdk.Color _color;
private int _height; private int _height;
private int _width; private int _width;
private int _topLeftRadius, _topRightRadius, _bottomLeftRadius, _bottomRightRadius; private int _topLeftRadius, _topRightRadius, _bottomLeftRadius, _bottomRightRadius;
public BoxViewDrawingArea() public void UpdateColor(Color color)
{ {
QueueResize(); _color = color;
QueueDraw();
} }
public Gdk.Color Color public void ResetColor()
{ {
get { return (_color); } UpdateColor(Color.Default);
set
{
_color = value;
QueueDraw();
}
} }
public int Height public void UpdateSize(int height, int width)
{ {
get { return (_height); } _height = height;
set _width = width;
{ QueueDraw();
_height = value;
QueueDraw();
}
}
public int Width
{
get { return (_width); }
set
{
_width = value;
QueueDraw();
}
} }
public int TopLeftRadius public void UpdateBorderRadius(int topLeftRadius = 5, int topRightRadius = 5, int bottomLeftRadius = 5, int bottomRightRadius = 5)
{ {
get { return (_topLeftRadius); } _topLeftRadius = topLeftRadius > 0 ? topLeftRadius : 0;
set _topRightRadius = topRightRadius > 0 ? topRightRadius : 0;
{ _bottomLeftRadius = bottomLeftRadius > 0 ? bottomLeftRadius : 0;
_topLeftRadius = value; _bottomRightRadius = bottomRightRadius > 0 ? bottomRightRadius : 0;
QueueDraw(); QueueDraw();
}
} }
public int TopRightRadius protected override void Draw(Gdk.Rectangle area, Context cr)
{ {
get { return (_topRightRadius); } if (_color.IsDefaultOrTransparent())
set
{ {
_topRightRadius = value; return;
QueueDraw();
}
}
public int BottomLeftRadius
{
get { return (_bottomLeftRadius); }
set
{
_bottomLeftRadius = value;
QueueDraw();
}
}
public int BottomRightRadius
{
get { return (_bottomRightRadius); }
set
{
_bottomRightRadius = value;
QueueDraw();
}
}
protected override bool OnExposeEvent(EventExpose ev)
{
using (var cr = CairoHelper.Create(GdkWindow))
{
Draw(cr, ev);
} }
return (true); double radius = _topLeftRadius;
}
private void Draw(Context cr, EventExpose ev)
{
_context = cr;
_event = ev;
DrawBoxView(_context, _event);
}
private void DrawBoxView(Context cr, EventExpose ev)
{
if (Color.Equal(Gdk.Color.Zero)) return;
int clipHeight = ev.Area.Height > 0 ? Height : 0;
int clipWidth = ev.Area.Width > 0 ? Width : 0;
double radius = TopLeftRadius;
int x = 0; int x = 0;
int y = 0; int y = 0;
int width = Width; int width = _width;
int height = Height; int height = _height;
cr.Rectangle(
radius,
0,
clipHeight,
clipWidth);
cr.MoveTo(x, y); cr.MoveTo(x, y);
cr.Arc(x + width - TopRightRadius, y + TopRightRadius, TopRightRadius, Math.PI * 1.5, Math.PI * 2); cr.Arc(x + width - _topRightRadius, y + _topRightRadius, _topRightRadius, Math.PI * 1.5, Math.PI * 2);
cr.Arc(x + width - BottomRightRadius, y + height - BottomRightRadius, BottomRightRadius, 0, Math.PI * .5); cr.Arc(x + width - _bottomRightRadius, y + height - _bottomRightRadius, _bottomRightRadius, 0, Math.PI * .5);
cr.Arc(x + BottomLeftRadius, y + height - BottomLeftRadius, BottomLeftRadius, Math.PI * .5, Math.PI); cr.Arc(x + _bottomLeftRadius, y + height - _bottomLeftRadius, _bottomLeftRadius, Math.PI * .5, Math.PI);
cr.Arc(x + TopLeftRadius, y + TopLeftRadius, TopLeftRadius, Math.PI, Math.PI * 1.5); cr.Arc(x + _topLeftRadius, y + _topLeftRadius, _topLeftRadius, Math.PI, Math.PI * 1.5);
var cairoColor = new Cairo.Color( cr.SetSourceRGBA(_color.R, _color.G, _color.B, _color.A);
(double)Color.Red / ushort.MaxValue,
(double)Color.Green / ushort.MaxValue,
(double)Color.Blue / ushort.MaxValue);
cr.SetSourceRGB(cairoColor.R, cairoColor.G, cairoColor.B);
cr.Fill(); cr.Fill();
} }

Просмотреть файл

@ -3,7 +3,7 @@ using Gtk;
namespace Xamarin.Forms.Platform.GTK.Controls namespace Xamarin.Forms.Platform.GTK.Controls
{ {
public class NotebookWrapper : EventBox public class NotebookWrapper : GtkFormsContainer
{ {
private Notebook _noteBook; private Notebook _noteBook;
private Pixbuf _backgroundPixbuf; private Pixbuf _backgroundPixbuf;
@ -86,7 +86,7 @@ namespace Xamarin.Forms.Platform.GTK.Controls
for (int i = 0; i < _noteBook.NPages; i++) for (int i = 0; i < _noteBook.NPages; i++)
{ {
var page = _noteBook.GetNthPage(i) as NotebookPageWrapper; var page = _noteBook.GetNthPage(i) as NotebookPageWrapper;
if (page?.Widget == widget) if (page?.Widget == widget)
{ {
_noteBook.RemovePage(i); _noteBook.RemovePage(i);

Просмотреть файл

@ -9,11 +9,11 @@ namespace Xamarin.Forms.Platform.GTK.Controls
public class Page : Table public class Page : Table
{ {
private Gdk.Rectangle _lastAllocation = Gdk.Rectangle.Zero; private Gdk.Rectangle _lastAllocation = Gdk.Rectangle.Zero;
private EventBox _headerContainer; private GtkFormsContainer _headerContainer;
private EventBox _contentContainerWrapper; private GtkFormsContainer _contentContainerWrapper;
private Fixed _contentContainer; private Fixed _contentContainer;
private HBox _toolbar; private HBox _toolbar;
private EventBox _content; private GtkFormsContainer _content;
private ImageControl _image; private ImageControl _image;
private Gdk.Color _defaultBackgroundColor; private Gdk.Color _defaultBackgroundColor;
@ -32,7 +32,7 @@ namespace Xamarin.Forms.Platform.GTK.Controls
} }
} }
public EventBox Content public GtkFormsContainer Content
{ {
get get
{ {
@ -52,29 +52,14 @@ namespace Xamarin.Forms.Platform.GTK.Controls
BuildPage(); BuildPage();
} }
public void SetToolbarColor(Gdk.Color? backgroundColor) public void SetToolbarColor(Color backgroundColor)
{ {
if (backgroundColor.HasValue) _headerContainer.SetBackgroundColor(backgroundColor);
{
_headerContainer.ModifyBg(StateType.Normal, backgroundColor.Value);
}
else
{
_headerContainer.ModifyBg(StateType.Normal, _defaultBackgroundColor);
}
} }
public void SetBackgroundColor(Gdk.Color? backgroundColor) public void SetBackgroundColor(Color backgroundColor)
{ {
if (backgroundColor != null) _contentContainerWrapper.SetBackgroundColor(backgroundColor);
{
_contentContainerWrapper.VisibleWindow = true;
_contentContainerWrapper.ModifyBg(StateType.Normal, backgroundColor.Value);
}
else
{
_contentContainerWrapper.VisibleWindow = false;
}
} }
public void SetBackgroundImage(string backgroundImagePath) public void SetBackgroundImage(string backgroundImagePath)
@ -113,7 +98,7 @@ namespace Xamarin.Forms.Platform.GTK.Controls
public override void Dispose() public override void Dispose()
{ {
base.Dispose(); base.Dispose();
if (_contentContainerWrapper != null) if (_contentContainerWrapper != null)
{ {
_contentContainerWrapper.SizeAllocated -= OnContentContainerWrapperSizeAllocated; _contentContainerWrapper.SizeAllocated -= OnContentContainerWrapperSizeAllocated;
@ -125,17 +110,17 @@ namespace Xamarin.Forms.Platform.GTK.Controls
_defaultBackgroundColor = Style.Backgrounds[(int)StateType.Normal]; _defaultBackgroundColor = Style.Backgrounds[(int)StateType.Normal];
_toolbar = new HBox(); _toolbar = new HBox();
_content = new EventBox(); _content = new GtkFormsContainer();
var root = new VBox(false, 0); var root = new VBox(false, 0);
_headerContainer = new EventBox(); _headerContainer = new GtkFormsContainer();
root.PackStart(_headerContainer, false, false, 0); root.PackStart(_headerContainer, false, false, 0);
_image = new ImageControl(); _image = new ImageControl();
_image.Aspect = ImageAspect.Fill; _image.Aspect = ImageAspect.Fill;
_contentContainerWrapper = new EventBox(); _contentContainerWrapper = new GtkFormsContainer();
_contentContainerWrapper.SizeAllocated += OnContentContainerWrapperSizeAllocated; _contentContainerWrapper.SizeAllocated += OnContentContainerWrapperSizeAllocated;
_contentContainer = new Fixed(); _contentContainer = new Fixed();
_contentContainer.Add(_image); _contentContainer.Add(_image);
@ -156,7 +141,7 @@ namespace Xamarin.Forms.Platform.GTK.Controls
_toolbar.ShowAll(); _toolbar.ShowAll();
} }
private void RefreshContent(EventBox newContent) private void RefreshContent(GtkFormsContainer newContent)
{ {
_contentContainer.RemoveFromContainer(_content); _contentContainer.RemoveFromContainer(_content);
_content = newContent; _content = newContent;

Просмотреть файл

@ -224,7 +224,7 @@ namespace Xamarin.Forms.Platform.GTK.Controls
} }
} }
public class TimePicker : Gtk.EventBox public class TimePicker : GtkFormsContainer
{ {
private const string DefaultTimeFormat = @"hh\:mm\:ss"; private const string DefaultTimeFormat = @"hh\:mm\:ss";

Просмотреть файл

@ -24,5 +24,6 @@
{ {
return color == Color.Transparent || color == Color.Default; return color == Color.Transparent || color == Color.Default;
} }
} }
} }

Просмотреть файл

@ -16,7 +16,7 @@ namespace Xamarin.Forms.Platform.GTK.Extensions
return true; return true;
} }
public static Gtk.EventBox CreateContainer(this Page view) public static GtkFormsContainer CreateContainer(this Page view)
{ {
if (!Forms.IsInitialized) if (!Forms.IsInitialized)
throw new InvalidOperationException("call Forms.Init() before this"); throw new InvalidOperationException("call Forms.Init() before this");

Просмотреть файл

@ -10,17 +10,17 @@ namespace Xamarin.Forms.Platform.GTK
private Application _application; private Application _application;
private Gdk.Size _lastSize; private Gdk.Size _lastSize;
public FormsWindow () public FormsWindow()
: base (WindowType.Toplevel) : base(WindowType.Toplevel)
{ {
SetDefaultSize (800, 600); SetDefaultSize(800, 600);
SetSizeRequest (400, 400); SetSizeRequest(400, 400);
MainThreadID = Thread.CurrentThread.ManagedThreadId; MainThreadID = Thread.CurrentThread.ManagedThreadId;
MainWindow = this; MainWindow = this;
if (SynchronizationContext.Current == null) if (SynchronizationContext.Current == null)
SynchronizationContext.SetSynchronizationContext (new GtkSynchronizationContext ()); SynchronizationContext.SetSynchronizationContext(new GtkSynchronizationContext());
WindowStateEvent += OnWindowStateEvent; WindowStateEvent += OnWindowStateEvent;
} }

Просмотреть файл

@ -0,0 +1,78 @@
using System;
using Cairo;
using Gdk;
using Gtk;
namespace Xamarin.Forms.Platform.GTK
{
/// <summary>
/// A generic container to embed visual elements.
/// </summary>
public class GtkFormsContainer : Gtk.EventBox
{
Color _backgroundColor;
public GtkFormsContainer()
{
VisibleWindow = false;
BackgroundColor = Color.Transparent;
}
Color BackgroundColor
{
get => _backgroundColor;
set
{
_backgroundColor = value;
QueueDraw();
}
}
public void SetBackgroundColor(Color color)
{
BackgroundColor = color;
}
/// <summary>
/// Subclasses can override this method to draw custom content over the background.
/// </summary>
/// <param name="clipArea">The clipped area that needs a redraw.</param>
/// <param name="cr">Context.</param>
protected virtual void Draw(Gdk.Rectangle clipArea, Context cr)
{
}
protected override bool OnExposeEvent(EventExpose evnt)
{
using (var cr = CairoHelper.Create(GdkWindow))
{
// Windowless widgets receive expose events with the whole area of
// of it's container, so we firt clip it to the allocation of the
// widget it self
var clipBox = Clip(evnt.Area);
// Draw first the background with the color defined in BackgroundColor
cr.Rectangle(clipBox.X, clipBox.Y, clipBox.Width, clipBox.Height);
cr.Clip();
cr.Save();
cr.SetSourceRGBA(BackgroundColor.R, BackgroundColor.G, BackgroundColor.B, BackgroundColor.A);
cr.Operator = Operator.Over;
cr.Paint();
cr.Restore();
// Let subclasses perform their own drawing operations
cr.Translate(Allocation.X, Allocation.Y);
Draw(clipBox, cr);
// And finally forward the expose event to the children
return base.OnExposeEvent(evnt);
}
}
Gdk.Rectangle Clip(Gdk.Rectangle area)
{
int startX = Math.Max(area.X, Allocation.X);
int endX = Math.Min(area.X + area.Width, Allocation.X + Allocation.Width);
int startY = Math.Max(area.Y, Allocation.Y);
int endY = Math.Min(area.Y + area.Height, Allocation.Y + Allocation.Height);
return new Gdk.Rectangle(startX, startY, endX - startX, endY - startY);
}
}
}

Просмотреть файл

@ -150,7 +150,7 @@ namespace Xamarin.Forms.Platform.GTK
e.PropertyName.Equals(Page.IconProperty.PropertyName)) e.PropertyName.Equals(Page.IconProperty.PropertyName))
UpdateToolBar(); UpdateToolBar();
} }
private string GetCurrentPageTitle() private string GetCurrentPageTitle()
{ {
if (_navigation == null) if (_navigation == null)
@ -169,15 +169,7 @@ namespace Xamarin.Forms.Platform.GTK
{ {
if (Navigation != null) if (Navigation != null)
{ {
if (Navigation.BarBackgroundColor.IsDefaultOrTransparent()) page?.SetToolbarColor(Navigation.BarBackgroundColor);
{
page?.SetToolbarColor(null);
}
else
{
var backgroundColor = Navigation.BarBackgroundColor.ToGtkColor();
page?.SetToolbarColor(backgroundColor);
}
} }
} }

Просмотреть файл

@ -1,5 +1,5 @@
using System; using System;
using Container = Gtk.EventBox; using Container = Xamarin.Forms.Platform.GTK.GtkFormsContainer;
namespace Xamarin.Forms.Platform.GTK namespace Xamarin.Forms.Platform.GTK
{ {

Просмотреть файл

@ -101,7 +101,7 @@ namespace Xamarin.Forms.Platform.GTK
return; return;
_disposed = true; _disposed = true;
MessagingCenter.Unsubscribe<Page, ActionSheetArguments>(this, Page.ActionSheetSignalName); MessagingCenter.Unsubscribe<Page, ActionSheetArguments>(this, Page.ActionSheetSignalName);
MessagingCenter.Unsubscribe<Page, AlertArguments>(this, Page.AlertSignalName); MessagingCenter.Unsubscribe<Page, AlertArguments>(this, Page.AlertSignalName);
MessagingCenter.Unsubscribe<Page, bool>(this, Page.BusySetSignalName); MessagingCenter.Unsubscribe<Page, bool>(this, Page.BusySetSignalName);

Просмотреть файл

@ -1,4 +1,4 @@
using Container = Gtk.EventBox; using Container = Xamarin.Forms.Platform.GTK.GtkFormsContainer;
namespace Xamarin.Forms.Platform.GTK namespace Xamarin.Forms.Platform.GTK
{ {

Просмотреть файл

@ -1,8 +1,6 @@
using Gtk; namespace Xamarin.Forms.Platform.GTK
namespace Xamarin.Forms.Platform.GTK
{ {
internal class PlatformRenderer : EventBox internal class PlatformRenderer : GtkFormsContainer
{ {
public PlatformRenderer(Platform platform) public PlatformRenderer(Platform platform)
{ {

Просмотреть файл

@ -4,7 +4,7 @@ using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
using Xamarin.Forms.Internals; using Xamarin.Forms.Internals;
using Xamarin.Forms.Platform.GTK.Extensions; using Xamarin.Forms.Platform.GTK.Extensions;
using Container = Gtk.EventBox; using Container = Xamarin.Forms.Platform.GTK.GtkFormsContainer;
namespace Xamarin.Forms.Platform.GTK.Renderers namespace Xamarin.Forms.Platform.GTK.Renderers
{ {
@ -20,6 +20,7 @@ namespace Xamarin.Forms.Platform.GTK.Renderers
protected AbstractPageRenderer() protected AbstractPageRenderer()
{ {
VisibleWindow = true;
_propertyChangedHandler = OnElementPropertyChanged; _propertyChangedHandler = OnElementPropertyChanged;
} }
@ -196,21 +197,11 @@ namespace Xamarin.Forms.Platform.GTK.Renderers
protected virtual void UpdateBackgroundColor() protected virtual void UpdateBackgroundColor()
{ {
Color backgroundColor = Element.BackgroundColor; Control.SetBackgroundColor(Element.BackgroundColor);
if (backgroundColor.IsDefaultOrTransparent())
{
Control.SetBackgroundColor(null);
}
else
{
Control.SetBackgroundColor(backgroundColor.ToGtkColor());
}
} }
protected virtual void UpdateBackgroundImage() protected virtual void UpdateBackgroundImage()
{ {
VisibleWindow = Page.ShouldDisplayNativeWindow();
Control.SetBackgroundImage(Page.BackgroundImage); Control.SetBackgroundImage(Page.BackgroundImage);
} }
@ -254,10 +245,9 @@ namespace Xamarin.Forms.Platform.GTK.Renderers
if (hasParentNavigation) break; if (hasParentNavigation) break;
current = parent; current = parent;
} }
var hasAncestorNavigationPage = hasParentNavigation && NavigationPage.GetHasNavigationBar(current); var hasAncestorNavigationPage = hasParentNavigation && NavigationPage.GetHasNavigationBar(current);
return hasAncestorNavigationPage; return hasAncestorNavigationPage;
} }
} }

Просмотреть файл

@ -33,26 +33,12 @@ namespace Xamarin.Forms.Platform.GTK.Renderers
UpdateIsRunning(); UpdateIsRunning();
} }
protected override void UpdateBackgroundColor()
{
base.UpdateBackgroundColor();
var backgroundColor = Element.BackgroundColor == Color.Default ? Color.Transparent.ToGtkColor() : Element.BackgroundColor.ToGtkColor();
Control.UpdateAlpha(Element.BackgroundColor == Color.Default ? 0.0 : 1.0);
Control.UpdateBackgroundColor(backgroundColor);
Container.VisibleWindow = true;
}
private void UpdateColor() private void UpdateColor()
{ {
if (Element == null || Control == null) if (Element == null || Control == null)
return; return;
var color = Element.Color == Color.Default ? Color.Default.ToGtkColor() : Element.Color.ToGtkColor(); Control.UpdateColor(Element.Color);
Control.UpdateColor(color);
} }
private void UpdateIsRunning() private void UpdateIsRunning()

Просмотреть файл

@ -47,11 +47,7 @@ namespace Xamarin.Forms.Platform.GTK.Renderers
{ {
base.UpdateBackgroundColor(); base.UpdateBackgroundColor();
var backgroundColor = Element.BackgroundColor == Color.Default ? Color.Transparent.ToGtkColor() : Element.BackgroundColor.ToGtkColor(); Control.SetBackgroundColor(Element.BackgroundColor);
Control.UpdateBackgroundColor(backgroundColor);
Container.VisibleWindow = true;
} }
private void SetColor(Color color) private void SetColor(Color color)
@ -65,8 +61,7 @@ namespace Xamarin.Forms.Platform.GTK.Renderers
} }
else else
{ {
var backgroundColor = color.ToGtkColor(); Control.UpdateColor(color);
Control.UpdateColor(backgroundColor);
} }
} }

Просмотреть файл

@ -69,7 +69,7 @@ namespace Xamarin.Forms.Platform.GTK.Renderers
Widget = new Carousel(); Widget = new Carousel();
Widget.Animated = true; Widget.Animated = true;
var eventBox = new EventBox(); var eventBox = new GtkFormsContainer();
eventBox.Add(Widget); eventBox.Add(Widget);
Control.Content = eventBox; Control.Content = eventBox;
} }
@ -134,7 +134,7 @@ namespace Xamarin.Forms.Platform.GTK.Renderers
} }
var newPages = new List<object>(); var newPages = new List<object>();
foreach(var pc in _pages) foreach (var pc in _pages)
{ {
newPages.Add(pc.Page); newPages.Add(pc.Page);
} }

Просмотреть файл

@ -73,7 +73,7 @@ namespace Xamarin.Forms.Platform.GTK.Renderers
// There is nothing similar in Gtk. // There is nothing similar in Gtk.
// Custom control has been created that simulates the expected behavior. // Custom control has been created that simulates the expected behavior.
Widget = new Controls.MasterDetailPage(); Widget = new Controls.MasterDetailPage();
var eventBox = new EventBox(); var eventBox = new GtkFormsContainer();
eventBox.Add(Widget); eventBox.Add(Widget);
Control.Content = eventBox; Control.Content = eventBox;

Просмотреть файл

@ -10,7 +10,7 @@ using Xamarin.Forms.Platform.GTK.Controls;
using Xamarin.Forms.Platform.GTK.Extensions; using Xamarin.Forms.Platform.GTK.Extensions;
using Xamarin.Forms.Platform.GTK.Helpers; using Xamarin.Forms.Platform.GTK.Helpers;
using Xamarin.Forms.PlatformConfiguration.GTKSpecific; using Xamarin.Forms.PlatformConfiguration.GTKSpecific;
using Container = Gtk.EventBox; using Container = Xamarin.Forms.Platform.GTK.GtkFormsContainer;
namespace Xamarin.Forms.Platform.GTK.Renderers namespace Xamarin.Forms.Platform.GTK.Renderers
{ {
@ -135,7 +135,7 @@ namespace Xamarin.Forms.Platform.GTK.Renderers
if (Widget == null) if (Widget == null)
{ {
Widget = new Fixed(); Widget = new Fixed();
var eventBox = new EventBox(); var eventBox = new GtkFormsContainer();
eventBox.Add(Widget); eventBox.Add(Widget);
Control.Content = eventBox; Control.Content = eventBox;
@ -393,7 +393,7 @@ namespace Xamarin.Forms.Platform.GTK.Renderers
int counter = 0; int counter = 0;
foreach(var item in items.Reverse()) foreach (var item in items.Reverse())
{ {
if (counter == index) if (counter == index)
{ {
@ -407,7 +407,7 @@ namespace Xamarin.Forms.Platform.GTK.Renderers
counter++; counter++;
} }
foreach (var child in Widget.Children) foreach (var child in Widget.Children)
{ {
child.Unparent(); child.Unparent();

Просмотреть файл

@ -138,7 +138,6 @@ namespace Xamarin.Forms.Platform.GTK.Renderers
if (renderer != null) if (renderer != null)
{ {
var content = renderer.Container; var content = renderer.Container;
content.VisibleWindow = false;
_viewPort.Add(content); _viewPort.Add(content);
} }
} }
@ -217,7 +216,7 @@ namespace Xamarin.Forms.Platform.GTK.Renderers
PolicyType ScrollBarVisibilityToGtk(ScrollBarVisibility visibility) PolicyType ScrollBarVisibilityToGtk(ScrollBarVisibility visibility)
{ {
switch(visibility) switch (visibility)
{ {
case ScrollBarVisibility.Default: case ScrollBarVisibility.Default:
return PolicyType.Automatic; return PolicyType.Automatic;

Просмотреть файл

@ -3,7 +3,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using Xamarin.Forms.Platform.GTK.Extensions; using Xamarin.Forms.Platform.GTK.Extensions;
using Container = Gtk.EventBox; using Container = Xamarin.Forms.Platform.GTK.GtkFormsContainer;
using Control = Gtk.Widget; using Control = Gtk.Widget;
namespace Xamarin.Forms.Platform.GTK namespace Xamarin.Forms.Platform.GTK
@ -237,16 +237,7 @@ namespace Xamarin.Forms.Platform.GTK
if (_disposed || Element == null || Control == null) if (_disposed || Element == null || Control == null)
return; return;
Color backgroundColor = Element.BackgroundColor; Container.SetBackgroundColor(Element.BackgroundColor);
bool isDefault = backgroundColor.IsDefaultOrTransparent();
if (!isDefault)
{
Container.ModifyBg(StateType.Normal, backgroundColor.ToGtkColor());
}
Container.VisibleWindow = !isDefault;
} }
protected virtual void SetAccessibilityHint() protected virtual void SetAccessibilityHint()

Просмотреть файл

@ -15,7 +15,7 @@ namespace Xamarin.Forms.Platform.GTK
private bool _isDisposed; private bool _isDisposed;
private TNativeElement _control; private TNativeElement _control;
private TElement _element; private TElement _element;
private EventBox _container; private GtkFormsContainer _container;
private bool _invalidateArrangeNeeded; private bool _invalidateArrangeNeeded;
private readonly NotifyCollectionChangedEventHandler _collectionChangedHandler; private readonly NotifyCollectionChangedEventHandler _collectionChangedHandler;
@ -27,7 +27,7 @@ namespace Xamarin.Forms.Platform.GTK
_collectionChangedHandler = ModelGestureRecognizersOnCollectionChanged; _collectionChangedHandler = ModelGestureRecognizersOnCollectionChanged;
} }
public EventBox Container public GtkFormsContainer Container
{ {
get { return _container; } get { return _container; }
set set
@ -178,8 +178,8 @@ namespace Xamarin.Forms.Platform.GTK
{ {
if (Element.Batched) if (Element.Batched)
{ {
if (e.PropertyName == VisualElement.XProperty.PropertyName || if (e.PropertyName == VisualElement.XProperty.PropertyName ||
e.PropertyName == VisualElement.YProperty.PropertyName || e.PropertyName == VisualElement.YProperty.PropertyName ||
e.PropertyName == VisualElement.WidthProperty.PropertyName || e.PropertyName == VisualElement.WidthProperty.PropertyName ||
e.PropertyName == VisualElement.HeightProperty.PropertyName) e.PropertyName == VisualElement.HeightProperty.PropertyName)
{ {
@ -188,7 +188,7 @@ namespace Xamarin.Forms.Platform.GTK
return; return;
} }
if (e.PropertyName == VisualElement.AnchorXProperty.PropertyName || if (e.PropertyName == VisualElement.AnchorXProperty.PropertyName ||
e.PropertyName == VisualElement.AnchorYProperty.PropertyName) e.PropertyName == VisualElement.AnchorYProperty.PropertyName)
{ {
UpdateScaleAndRotation(Element, Container); UpdateScaleAndRotation(Element, Container);
@ -197,10 +197,10 @@ namespace Xamarin.Forms.Platform.GTK
{ {
UpdateScaleAndRotation(Element, Container); UpdateScaleAndRotation(Element, Container);
} }
else if (e.PropertyName == VisualElement.TranslationXProperty.PropertyName || else if (e.PropertyName == VisualElement.TranslationXProperty.PropertyName ||
e.PropertyName == VisualElement.TranslationYProperty.PropertyName || e.PropertyName == VisualElement.TranslationYProperty.PropertyName ||
e.PropertyName == VisualElement.RotationProperty.PropertyName || e.PropertyName == VisualElement.RotationProperty.PropertyName ||
e.PropertyName == VisualElement.RotationXProperty.PropertyName || e.PropertyName == VisualElement.RotationXProperty.PropertyName ||
e.PropertyName == VisualElement.RotationYProperty.PropertyName) e.PropertyName == VisualElement.RotationYProperty.PropertyName)
{ {
UpdateRotation(Element, Container); UpdateRotation(Element, Container);
@ -274,7 +274,7 @@ namespace Xamarin.Forms.Platform.GTK
} }
// TODO: Implement Scale // TODO: Implement Scale
private static void UpdateScaleAndRotation(VisualElement view, EventBox eventBox) private static void UpdateScaleAndRotation(VisualElement view, Gtk.Widget eventBox)
{ {
double anchorX = view.AnchorX; double anchorX = view.AnchorX;
double anchorY = view.AnchorY; double anchorY = view.AnchorY;
@ -284,7 +284,7 @@ namespace Xamarin.Forms.Platform.GTK
} }
// TODO: Implement Rotation // TODO: Implement Rotation
private static void UpdateRotation(VisualElement view, EventBox eventBox) private static void UpdateRotation(VisualElement view, Gtk.Widget eventBox)
{ {
if (view == null) if (view == null)
return; return;
@ -320,21 +320,21 @@ namespace Xamarin.Forms.Platform.GTK
} }
} }
private static void UpdateVisibility(VisualElement view, EventBox eventBox) private static void UpdateVisibility(VisualElement view, Gtk.Widget eventBox)
{ {
eventBox.Visible = view.IsVisible; eventBox.Visible = view.IsVisible;
} }
// TODO: Implement Opacity // TODO: Implement Opacity
private static void UpdateOpacity(VisualElement view, EventBox eventBox) private static void UpdateOpacity(VisualElement view, Gtk.Widget eventBox)
{ {
} }
// TODO: Implement InputTransparent // TODO: Implement InputTransparent
private static void UpdateInputTransparent(VisualElement view, EventBox eventBox) private static void UpdateInputTransparent(VisualElement view, Gtk.Widget eventBox)
{ {
} }
private void OnContainerButtonPressEvent(object o, ButtonPressEventArgs args) private void OnContainerButtonPressEvent(object o, ButtonPressEventArgs args)

Просмотреть файл

@ -211,6 +211,7 @@
<Compile Include="ViewRenderer.cs" /> <Compile Include="ViewRenderer.cs" />
<Compile Include="VisualElementRenderer.cs" /> <Compile Include="VisualElementRenderer.cs" />
<Compile Include="VisualElementTracker.cs" /> <Compile Include="VisualElementTracker.cs" />
<Compile Include="GtkFormsContainer.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Xamarin.Forms.Core\Xamarin.Forms.Core.csproj"> <ProjectReference Include="..\Xamarin.Forms.Core\Xamarin.Forms.Core.csproj">