Conflicts:
	Xwt.WPF/Xwt.WPFBackend/FontBackendHandler.cs
	Xwt.WPF/Xwt.WPFBackend/ImageHandler.cs
This commit is contained in:
Lluis Sanchez 2013-03-27 14:18:32 +01:00
Родитель 1fc6817a50 dae886df2f
Коммит de2182cb2d
103 изменённых файлов: 1854 добавлений и 876 удалений

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

@ -1,6 +1,7 @@
using System;
using Xwt;
using Xwt.Drawing;
using System.Xml;
namespace Samples
{
@ -59,7 +60,7 @@ namespace Samples
HPaned box = new HPaned ();
icon = Image.FromResource (typeof(App), "class.png");
icon = Image.FromResource (typeof(App), "document-generic.png");
store = new TreeStore (nameCol, iconCol, widgetCol);
samplesTree = new TreeView ();
@ -155,7 +156,7 @@ namespace Samples
sampleBox.PackStart (s.Widget, BoxMode.FillAndExpand);
}
// string txt = System.Xaml.XamlServices.Save (s);
// Console.WriteLine (System.Xaml.XamlServices.Save (s.Widget));
currentSample = s.Widget;
Dump (currentSample, 0);
}

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

@ -191,6 +191,12 @@
<LogicalName>cow.jpg</LogicalName>
<DeployService-Deploy>True</DeployService-Deploy>
</EmbeddedResource>
<EmbeddedResource Include="document-generic.png">
<LogicalName>document-generic.png</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="document-generic%402x.png">
<LogicalName>document-generic@2x.png</LogicalName>
</EmbeddedResource>
</ItemGroup>
<ProjectExtensions>
<MonoDevelop>

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

@ -54,14 +54,14 @@ namespace Samples
// Image
var arcColor = new Color (1, 0, 1);
ImageBuilder ib = new ImageBuilder (30, 30, ImageFormat.ARGB32);
ImageBuilder ib = new ImageBuilder (30, 30);
ib.Context.Arc (15, 15, 15, 0, 360);
ib.Context.SetColor (arcColor);
ib.Context.Fill ();
ib.Context.SetColor (Colors.DarkKhaki);
ib.Context.Rectangle (0, 0, 5, 5);
ib.Context.Fill ();
var img = ib.ToImage ();
var img = ib.ToVectorImage ();
ctx.DrawImage (img, 0, 0);
ctx.DrawImage (img, 0, 50, 50, 10);

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

@ -50,7 +50,7 @@ namespace Samples
var col2 = new Rectangle ();
var text = new TextLayout (ctx);
text.Font = this.Font.WithPointSize (24);
text.Font = this.Font.WithSize (24);
Console.WriteLine (text.Font.Size);
// first text
@ -118,7 +118,7 @@ namespace Samples
// proofing rotate, and printing size to see the values
ctx.Save ();
text.Font = this.Font.WithPointSize (10);
text.Font = this.Font.WithSize (10);
text.Text = string.Format ("Size 1 {0}\r\nSize 2 {1}\r\nSize 3 {2} Scale {3}",
size1, size2, size3, scale);
text.Width = -1; // this clears textsize
@ -136,7 +136,7 @@ namespace Samples
TextLayout tl0 = new TextLayout (this);
tl0.Font = this.Font.WithPointSize (10);
tl0.Font = this.Font.WithSize (10);
tl0.Text = "This text contains attributes.";
tl0.SetUnderline ( 0, "This".Length);
tl0.SetForeground (new Color (0, 1.0, 1.0), "This ".Length, "text".Length);

Двоичные данные
Samples/document-generic.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 423 B

Двоичные данные
Samples/document-generic@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 918 B

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

@ -57,7 +57,7 @@ namespace Xwt
{
if (builder == null)
return;
var img = builder.ToImage ();
var img = builder.ToBitmap ();
builder.Dispose ();
builder = null;

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

@ -31,7 +31,7 @@ namespace Xwt
{
public override Widget CreateWidget ()
{
return new ImageView (StockIcons.Warning.WithBoxSize (16));
return new ImageView (StockIcons.Warning.WithSize (IconSize.Small));
}
}
}

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

@ -129,7 +129,7 @@ namespace Xwt
var bmp1 = img1.ToBitmap ();
var bmp2 = img2.ToBitmap ();
var res = new ImageBuilder ((int)Math.Min (bmp1.Size.Width, bmp2.Size.Width), (int) Math.Min (bmp1.Size.Height, bmp2.Size.Height));
var bmpr = res.ToImage ().ToBitmap ();
var bmpr = res.ToBitmap ();
res.Dispose ();
for (int y=0; y<bmp1.Size.Height && y < bmp2.Size.Height; y++) {
for (int x=0; x<bmp1.Size.Width && x<bmp2.Size.Height; x++) {

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

@ -33,9 +33,6 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />

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

@ -29,6 +29,7 @@ using System;
using Xwt.Backends;
using Xwt.Drawing;
using Xwt.GtkBackend;
namespace Xwt.CairoBackend
{
@ -37,6 +38,12 @@ namespace Xwt.CairoBackend
public double GlobalAlpha = 1;
public Cairo.Context Context;
public Cairo.Surface TempSurface;
public double ScaleFactor = 1;
public CairoContextBackend (double scaleFactor)
{
ScaleFactor = scaleFactor;
}
public void Dispose ()
{
@ -53,10 +60,6 @@ namespace Xwt.CairoBackend
public class CairoContextBackendHandler: ContextBackendHandler
{
public CairoContextBackendHandler ()
{
}
#region IContextBackendHandler implementation
public override void Save (object backend)
@ -210,6 +213,8 @@ namespace Xwt.CairoBackend
public override void SetPattern (object backend, object p)
{
Cairo.Context ctx = ((CairoContextBackend)backend).Context;
if (p is ImagePatternBackend)
p = ((ImagePatternBackend)p).GetPattern (ApplicationContext, ((CairoContextBackend)backend).ScaleFactor);
if (p != null)
ctx.Pattern = (Cairo.Pattern) p;
else
@ -227,46 +232,17 @@ namespace Xwt.CairoBackend
CairoTextLayoutBackendHandler.Draw (ctx, lb, x, y);
}
protected virtual void SetSourceImage (Cairo.Context ctx, object img, double x, double y)
{
}
public override bool CanDrawImage (object backend, object img)
{
return true;
}
public override void DrawImage (object backend, object img, double x, double y, double width, double height, double alpha)
public override void DrawImage (object backend, ImageDescription img, double x, double y)
{
CairoContextBackend ctx = (CairoContextBackend)backend;
alpha = alpha * ctx.GlobalAlpha;
img = ResolveImage (img, width, height);
var s = GetImageSize (img);
img.Alpha *= ctx.GlobalAlpha;
var pix = (Xwt.GtkBackend.GtkImage) img.Backend;
if (s.Width == width && s.Height == height) {
SetSourceImage (ctx.Context, img, x, y);
if (alpha == 1)
ctx.Context.Paint ();
else
ctx.Context.PaintWithAlpha (alpha);
return;
pix.Draw (ApplicationContext, ctx.Context, ctx.ScaleFactor, x, y, img);
}
ctx.Context.Save ();
double sx = ((double) width) / s.Width;
double sy = ((double) height) / s.Height;
ctx.Context.Translate (x, y);
ctx.Context.Scale (sx, sy);
SetSourceImage (ctx.Context, img, 0, 0);
if (alpha == 1)
ctx.Context.Paint ();
else
ctx.Context.PaintWithAlpha (alpha);
ctx.Context.Restore ();
}
public override void DrawImage (object backend, object img, Rectangle srcRect, Rectangle destRect, double width, double height, double alpha)
public override void DrawImage (object backend, ImageDescription img, Rectangle srcRect, Rectangle destRect)
{
CairoContextBackend ctx = (CairoContextBackend)backend;
ctx.Context.Save ();
@ -277,12 +253,10 @@ namespace Xwt.CairoBackend
double sx = destRect.Width / srcRect.Width;
double sy = destRect.Height / srcRect.Height;
ctx.Context.Scale (sx, sy);
SetSourceImage (ctx.Context, img, 0, 0);
alpha = alpha * ctx.GlobalAlpha;
if (alpha == 1)
ctx.Context.Paint ();
else
ctx.Context.PaintWithAlpha (alpha);
img.Alpha *= ctx.GlobalAlpha;
var pix = (Xwt.GtkBackend.GtkImage) img.Backend;
pix.Draw (ApplicationContext, ctx.Context, ctx.ScaleFactor, 0, 0, img);
ctx.Context.Restore ();
}
@ -291,11 +265,6 @@ namespace Xwt.CairoBackend
return new Size (0,0);
}
protected virtual object ResolveImage (object img, double width, double height)
{
return img;
}
public override void Rotate (object backend, double angle)
{
CairoContextBackend gc = (CairoContextBackend)backend;
@ -324,7 +293,7 @@ namespace Xwt.CairoBackend
public override object CreatePath ()
{
Cairo.Surface sf = new Cairo.ImageSurface (null, Cairo.Format.A1, 0, 0, 0);
return new CairoContextBackend {
return new CairoContextBackend (1) { // scale doesn't matter here, we are going to use it only for creating a path
TempSurface = sf,
Context = new Cairo.Context (sf)
};

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

@ -29,6 +29,7 @@ using Xwt.Backends;
using Xwt.Drawing;
using System.Collections.Generic;
using Xwt.GtkBackend;
namespace Xwt.CairoBackend
{
@ -71,7 +72,8 @@ namespace Xwt.CairoBackend
public override object Create (ICanvasBackend canvas)
{
LayoutBackend b = new LayoutBackend ();
CairoContextBackend ba = new CairoContextBackend ();
var w = ((WidgetBackend)canvas).Widget;
CairoContextBackend ba = new CairoContextBackend (Xwt.GtkBackend.Util.GetScaleFactor (w));
ba.Context = SharedContext;
b.Context = ba;
return b;

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

@ -28,12 +28,13 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Gtk;
using Xwt.Backends;
namespace Xwt.GtkBackend
{
public static class CellUtil
{
public static Gtk.CellRenderer CreateCellRenderer (ICellRendererTarget col, object target, CellView view, Gtk.TreeModel model)
public static Gtk.CellRenderer CreateCellRenderer (ApplicationContext actx, ICellRendererTarget col, object target, CellView view, Gtk.TreeModel model)
{
if (view is TextCellView) {
Gtk.CellRendererText cr = new Gtk.CellRendererText ();
@ -56,9 +57,9 @@ namespace Xwt.GtkBackend
return cr;
}
else if (view is ImageCellView) {
Gtk.CellRendererPixbuf cr = new Gtk.CellRendererPixbuf ();
CellRendererImage cr = new CellRendererImage (actx);
col.PackStart (target, cr, false);
col.AddAttribute (target, cr, "pixbuf", ((ImageCellView)view).ImageField.Index);
col.AddAttribute (target, cr, "image", ((ImageCellView)view).ImageField.Index);
return cr;
}
else if (view is CanvasCellView) {
@ -74,20 +75,20 @@ namespace Xwt.GtkBackend
throw new NotSupportedException ("Unknown cell view type: " + view.GetType ());
}
public static Gtk.Widget CreateCellRenderer (ICollection<CellView> views)
public static Gtk.Widget CreateCellRenderer (ApplicationContext actx, ICollection<CellView> views)
{
if (views.Count == 1) {
Gtk.HBox box = new Gtk.HBox ();
foreach (var v in views)
box.PackStart (CreateCellRenderer (v), false, false, 0);
box.PackStart (CreateCellRenderer (actx, v), false, false, 0);
box.ShowAll ();
return box;
}
else
return CreateCellRenderer (views.First ());
return CreateCellRenderer (actx, views.First ());
}
public static Gtk.Widget CreateCellRenderer (CellView view)
public static Gtk.Widget CreateCellRenderer (ApplicationContext actx, CellView view)
{
if (view is TextCellView) {
Gtk.Label lab = new Gtk.Label ();
@ -106,5 +107,62 @@ namespace Xwt.GtkBackend
void AddAttribute (object target, Gtk.CellRenderer cr, string field, int column);
void SetCellDataFunc (object target, Gtk.CellRenderer cr, Gtk.CellLayoutDataFunc dataFunc);
}
public class CellRendererImage: Gtk.CellRenderer, ICellDataSource
{
TreeModel treeModel;
TreeIter iter;
ImageDescription image;
ApplicationContext actx;
public CellRendererImage (ApplicationContext actx)
{
this.actx = actx;
}
#region ICellDataSource implementation
public void LoadData (CellLayout cell_layout, CellRenderer cell, TreeModel treeModel, TreeIter iter)
{
this.treeModel = treeModel;
this.iter = iter;
}
object ICellDataSource.GetValue (IDataField field)
{
return treeModel.GetValue (iter, field.Index);
}
#endregion
[GLib.Property ("image")]
public ImageDescription Image {
get { return image; }
set { image = value; }
}
protected override void Render (Gdk.Drawable window, Gtk.Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, Gtk.CellRendererState flags)
{
if (image.IsNull)
return;
var ctx = Gdk.CairoHelper.Create (window);
using (ctx) {
var pix = ((GtkImage)image.Backend);
pix.Draw (actx, ctx, Util.GetScaleFactor (widget), cell_area.X, cell_area.Y, image);
}
}
public override void GetSize (Gtk.Widget widget, ref Gdk.Rectangle cell_area, out int x_offset, out int y_offset, out int width, out int height)
{
if (image.IsNull) {
width = height = 0;
} else {
width = (int) image.Size.Width;
height = (int) image.Size.Height;
}
x_offset = y_offset = 0;
}
}
}

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

@ -59,7 +59,7 @@ namespace Xwt.GtkBackend
{
ICanvasCellRenderer cell = cellView;
cell.ApplicationContext.InvokeUserCode (delegate {
CairoContextBackend ctx = new CairoContextBackend ();
CairoContextBackend ctx = new CairoContextBackend (Util.GetScaleFactor (widget));
ctx.Context = Gdk.CairoHelper.Create (window);
using (ctx) {
cell.Draw (ctx, new Rectangle (cell_area.X, cell_area.Y, cell_area.Width, cell_area.Height));

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

@ -59,14 +59,22 @@ namespace Xwt.GtkBackend
{
public class AlertDialogBackend: IAlertDialogBackend
{
ApplicationContext context;
#region IAlertDialogBackend implementation
public void Dispose ()
{
}
public void Initialize (ApplicationContext context)
{
this.context = context;
}
public Command Run (WindowFrame transientFor, MessageDescription message)
{ GtkAlertDialog alertDialog = new GtkAlertDialog (message);
{
GtkAlertDialog alertDialog = new GtkAlertDialog (context, message);
alertDialog.FocusButton (message.DefaultButton);
var wb = (WindowFrameBackend)Toolkit.GetBackend (transientFor);
var win = wb != null ? wb.Window : null;

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

@ -34,6 +34,7 @@ namespace Xwt.GtkBackend
public class ButtonBackend: WidgetBackend, IButtonBackend
{
protected bool ignoreClickEvents;
ImageDescription image;
public ButtonBackend ()
{
@ -55,13 +56,15 @@ namespace Xwt.GtkBackend
get { return (IButtonEventSink)base.EventSink; }
}
public void SetContent (string label, Image image, ContentPosition position)
public void SetContent (string label, ImageDescription image, ContentPosition position)
{
this.image = image;
if (label != null && label.Length == 0)
label = null;
Button b = (Button) Frontend;
if (label != null && image == null && b.Type == ButtonType.Normal) {
if (label != null && image.Backend == null && b.Type == ButtonType.Normal) {
Widget.Label = label;
return;
}
@ -76,8 +79,8 @@ namespace Xwt.GtkBackend
Gtk.Widget contentWidget = null;
Gtk.Widget imageWidget = null;
if (image != null)
imageWidget = new Gtk.Image (image.ToPixbuf (Gtk.IconSize.Button));
if (image.Backend != null)
imageWidget = new ImageBox (ApplicationContext, image.WithDefaultSize (Gtk.IconSize.Button));
if (label != null && imageWidget == null) {
contentWidget = new Gtk.Label (label);
@ -138,7 +141,7 @@ namespace Xwt.GtkBackend
public void SetButtonType (ButtonType type)
{
Button b = (Button) Frontend;
SetContent (b.Label, b.Image, b.ImagePosition);
SetContent (b.Label, image, b.ImagePosition);
}
public override void EnableEvent (object eventId)

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

@ -185,7 +185,7 @@ namespace Xwt.GtkBackend
public CairoContextBackend CreateContext ()
{
CairoContextBackend ctx = new CairoContextBackend ();
CairoContextBackend ctx = new CairoContextBackend (Util.GetScaleFactor (this));
if (!IsRealized) {
Cairo.Surface sf = new Cairo.ImageSurface (Cairo.Format.ARGB32, 1, 1);
Cairo.Context c = new Cairo.Context (sf);

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

@ -99,7 +99,7 @@ namespace Xwt.GtkBackend
{
Widget.Clear ();
foreach (var v in views)
CellUtil.CreateCellRenderer (this, null, v, Widget.Model);
CellUtil.CreateCellRenderer (ApplicationContext, this, null, v, Widget.Model);
}
public void SetSource (IListDataSource source, IBackend sourceBackend)

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

@ -32,29 +32,7 @@ using Xwt.Backends;
namespace Xwt.GtkBackend
{
public class ContextBackendHandler: CairoContextBackendHandler
{
protected override object ResolveImage (object img, double width, double height)
{
if (img is String)
return ImageHandler.CreateBitmap ((string)img, width, height);
else
return img;
}
protected override void SetSourceImage (Cairo.Context ctx, object img, double x, double y)
{
Gdk.CairoHelper.SetSourcePixbuf (ctx, (Gdk.Pixbuf)img, x, y);
}
protected override Size GetImageSize (object img)
{
Gdk.Pixbuf pb = (Gdk.Pixbuf)img;
return new Size (pb.Width, pb.Height);
}
}
public class ContextBackendHandlerWithPango: ContextBackendHandler
public class ContextBackendHandlerWithPango: CairoContextBackendHandler
{
public override void DrawTextLayout (object backend, TextLayout layout, double x, double y)
{

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

@ -90,12 +90,12 @@ namespace Xwt.GtkBackend
if (!string.IsNullOrEmpty (btn.Label) && btn.Image == null) {
b.Label = btn.Label;
} else if (string.IsNullOrEmpty (btn.Label) && btn.Image != null) {
var pix = (Gdk.Pixbuf) Toolkit.GetBackend (btn.Image);
b.Image = new Gtk.Image (pix);
var pix = ToolkitEngineBackend.GetImageDescription (btn.Image);
b.Image = new ImageBox (ApplicationContext, pix);
} else if (!string.IsNullOrEmpty (btn.Label)) {
Gtk.Box box = new Gtk.HBox (false, 3);
var pix = (Gdk.Pixbuf) Toolkit.GetBackend (btn.Image);
box.PackStart (new Gtk.Image (pix), false, false, 0);
var pix = ToolkitEngineBackend.GetImageDescription (btn.Image);
box.PackStart (new ImageBox (ApplicationContext, pix), false, false, 0);
box.PackStart (new Gtk.Label (btn.Label), true, true, 0);
b.Image = box;
}

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

@ -28,15 +28,15 @@ using System;
using Xwt.Backends;
using Pango;
using Xwt.Drawing;
using System.Globalization;
namespace Xwt.GtkBackend
{
public class GtkFontBackendHandler: FontBackendHandler
{
public override object Create (string fontName, double size, FontSizeUnit sizeUnit, FontStyle style, FontWeight weight, FontStretch stretch)
public override object Create (string fontName, double size, FontStyle style, FontWeight weight, FontStretch stretch)
{
string s = sizeUnit == FontSizeUnit.Points ? size.ToString () : size + "px";
return FontDescription.FromString (fontName + " " + s);
return FontDescription.FromString (fontName + " " + size.ToString (CultureInfo.InvariantCulture));
}
#region IFontBackendHandler implementation
@ -47,14 +47,11 @@ namespace Xwt.GtkBackend
return d.Copy ();
}
public override object SetSize (object handle, double size, FontSizeUnit sizeUnit)
public override object SetSize (object handle, double size)
{
FontDescription d = (FontDescription) handle;
d = d.Copy ();
if (sizeUnit == FontSizeUnit.Points)
d.Size = (int) (size * Pango.Scale.PangoScale);
else
d.AbsoluteSize = (int) (size * Pango.Scale.PangoScale);
return d;
}

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

@ -30,6 +30,7 @@ using System;
using System.Text;
using Gtk;
using System.Linq;
using Xwt.Backends;
namespace Xwt.GtkBackend
{
@ -38,11 +39,12 @@ namespace Xwt.GtkBackend
/// </summary>
internal class GtkAlertDialog : Gtk.Dialog
{
ApplicationContext actx;
Command resultButton = null;
Command[] buttons;
Gtk.HBox hbox = new Gtk.HBox ();
Gtk.Image image = new Gtk.Image ();
ImageBox image;
Gtk.Label label = new Gtk.Label ();
Gtk.VBox labelsBox = new Gtk.VBox (false, 6);
@ -56,6 +58,7 @@ namespace Xwt.GtkBackend
void Init ()
{
image = new ImageBox (actx);
VBox.PackStart (hbox);
hbox.PackStart (image, false, false, 0);
hbox.PackStart (labelsBox, true, true, 0);
@ -86,8 +89,9 @@ namespace Xwt.GtkBackend
this.label.Xalign = 0.00f;
}
public GtkAlertDialog (MessageDescription message)
public GtkAlertDialog (ApplicationContext actx, MessageDescription message)
{
this.actx = actx;
Init ();
this.buttons = message.Buttons.ToArray ();
@ -102,7 +106,8 @@ namespace Xwt.GtkBackend
secondaryText = message.SecondaryText;
}
image.SetFromStock (Util.ToGtkStock (message.Icon), Gtk.IconSize.Dialog);
var icon = ToolkitEngineBackend.GetImageDescription (message.Icon);
image.Image = icon.WithDefaultSize (Gtk.IconSize.Dialog);
StringBuilder markup = new StringBuilder (@"<span weight=""bold"" size=""larger"">");
markup.Append (GLib.Markup.EscapeText (primaryText));
@ -123,8 +128,10 @@ namespace Xwt.GtkBackend
newButton.Label = button.Label;
newButton.UseUnderline = true;
newButton.UseStock = button.IsStockButton;
if (button.Icon != null)
newButton.Image = new Gtk.Image (button.Icon.ToPixbuf (Gtk.IconSize.Button));
if (button.Icon != null) {
icon = ToolkitEngineBackend.GetImageDescription (button.Icon);
newButton.Image = new ImageBox (actx, icon.WithDefaultSize (Gtk.IconSize.Button));
}
newButton.Clicked += ButtonClicked;
ActionArea.Add (newButton);
}

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

@ -50,14 +50,19 @@ namespace Xwt.GtkBackend
public override object CreateContext (object backend)
{
Cairo.Surface sf = (Cairo.Surface) backend;
CairoContextBackend ctx = new CairoContextBackend ();
CairoContextBackend ctx = new CairoContextBackend (1);
ctx.Context = new Cairo.Context (sf);
return ctx;
}
public override object CreateImage (object backend)
{
Cairo.ImageSurface sf = (Cairo.ImageSurface) backend;
var pix = CreatePixbuf ((Cairo.ImageSurface)backend);
return new GtkImage (pix);
}
public static Gdk.Pixbuf CreatePixbuf (Cairo.ImageSurface sf)
{
byte[] cdata = sf.Data;
int nbytes = sf.Format == Cairo.Format.ARGB32 ? 4 : 3;
byte[] data = new byte[(cdata.Length / 4) * nbytes];

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

@ -27,6 +27,9 @@
using System;
using Xwt.Backends;
using Xwt.Drawing;
using System.Collections.Generic;
using Xwt.CairoBackend;
using System.Linq;
namespace Xwt.GtkBackend
{
@ -35,16 +38,26 @@ namespace Xwt.GtkBackend
public override object LoadFromStream (System.IO.Stream stream)
{
using (Gdk.PixbufLoader loader = new Gdk.PixbufLoader (stream))
return loader.Pixbuf;
return new GtkImage (loader.Pixbuf);
}
public override void SaveToStream (object backend, System.IO.Stream stream, ImageFileType fileType)
{
var pix = (Gdk.Pixbuf)backend;
var buffer = pix.SaveToBuffer (GetFileType (fileType));
var pix = (GtkImage)backend;
var buffer = pix.Frames[0].SaveToBuffer (GetFileType (fileType));
stream.Write (buffer, 0, buffer.Length);
}
public override object CreateCustomDrawn (ImageDrawCallback drawCallback)
{
return new GtkImage (drawCallback);
}
public override object CreateMultiSizeImage (IEnumerable<object> images)
{
return new GtkImage (images.Cast<GtkImage> ().Select (img => img.Frames [0]));
}
string GetFileType (ImageFileType type)
{
switch (type) {
@ -66,7 +79,7 @@ namespace Xwt.GtkBackend
public override void SetBitmapPixel (object handle, int x, int y, Xwt.Drawing.Color color)
{
var pix = (Gdk.Pixbuf)handle;
var pix = ((GtkImage)handle).Frames[0];
unsafe {
byte* p = (byte*) pix.Pixels;
@ -80,7 +93,7 @@ namespace Xwt.GtkBackend
public override Xwt.Drawing.Color GetBitmapPixel (object handle, int x, int y)
{
var pix = (Gdk.Pixbuf)handle;
var pix = ((GtkImage)handle).Frames[0];
unsafe {
byte* p = (byte*) pix.Pixels;
@ -91,80 +104,52 @@ namespace Xwt.GtkBackend
public override void Dispose (object backend)
{
((Gdk.Pixbuf)backend).Dispose ();
((GtkImage)backend).Dispose ();
}
public override bool HasMultipleSizes (object handle)
{
return handle is string;
return ((GtkImage)handle).HasMultipleSizes;
}
public override Size GetSize (object handle)
{
var pix = handle as Gdk.Pixbuf;
if (pix != null)
return new Size (pix.Width, pix.Height);
else if (handle is String)
return new Size (48, 48); // Return a default size
else
return Size.Zero;
}
public override object ResizeBitmap (object handle, double width, double height)
{
var pix = (Gdk.Pixbuf)handle;
return pix.ScaleSimple ((int)width, (int)height, Gdk.InterpType.Bilinear);
var pix = handle as GtkImage;
return pix.DefaultSize;
}
public override object CopyBitmap (object handle)
{
var pix = (Gdk.Pixbuf)handle;
return pix.Copy ();
var pix = ((GtkImage)handle).Frames[0];
return new GtkImage (pix.Copy ());
}
public override void CopyBitmapArea (object srcHandle, int srcX, int srcY, int width, int height, object destHandle, int destX, int destY)
{
var pixSrc = (Gdk.Pixbuf)srcHandle;
var pixDst = (Gdk.Pixbuf)destHandle;
var pixSrc = ((GtkImage)srcHandle).Frames[0];
var pixDst = ((GtkImage)destHandle).Frames[0];
pixSrc.CopyArea (srcX, srcY, width, height, pixDst, destX, destY);
}
public override object CropBitmap (object handle, int srcX, int srcY, int width, int height)
{
var pix = (Gdk.Pixbuf)handle;
var pix = ((GtkImage)handle).Frames[0];
Gdk.Pixbuf res = new Gdk.Pixbuf (pix.Colorspace, pix.HasAlpha, pix.BitsPerSample, width, height);
res.Fill (0);
pix.CopyArea (srcX, srcY, width, height, res, 0, 0);
return res;
}
public override object ChangeBitmapOpacity (object backend, double opacity)
{
Gdk.Pixbuf image = (Gdk.Pixbuf) backend;
Gdk.Pixbuf result = image.Copy ();
result.Fill (0);
result = result.AddAlpha (true, 0, 0, 0);
image.Composite (result, 0, 0, image.Width, image.Height, 0, 0, 1, 1, Gdk.InterpType.Bilinear, (int)(255 * opacity));
return result;
return new GtkImage (res);
}
public override bool IsBitmap (object handle)
{
return handle is Gdk.Pixbuf;
var img = (GtkImage) handle;
return !img.HasMultipleSizes;
}
public override object ConvertToBitmap (object handle, double width, double height)
public override object ConvertToBitmap (object handle, int pixelWidth, int pixelHeight, ImageFormat format)
{
Gdk.Pixbuf result = CreateBitmap ((string)handle, width, height);
if (result != null) {
int bw = (int) width;
int bh = (int) height;
if (result.Width != bw || result.Height != bh)
return ResizeBitmap (result, bw, bh);
}
return result;
var img = (GtkImage) handle;
return new GtkImage (img.GetBestFrame (ApplicationContext, 1, pixelWidth, pixelHeight, true));
}
internal static Gdk.Pixbuf CreateBitmap (string stockId, double width, double height)
@ -184,5 +169,209 @@ namespace Xwt.GtkBackend
return result;
}
}
public class GtkImage: IDisposable
{
Gdk.Pixbuf[] frames;
ImageDrawCallback drawCallback;
string stockId;
public Gdk.Pixbuf[] Frames {
get { return frames; }
}
public GtkImage (Gdk.Pixbuf img)
{
this.frames = new Gdk.Pixbuf [] { img };
}
public GtkImage (string stockId)
{
this.stockId = stockId;
}
public GtkImage (IEnumerable<Gdk.Pixbuf> frames)
{
this.frames = frames.ToArray ();
}
public GtkImage (ImageDrawCallback drawCallback)
{
this.drawCallback = drawCallback;
}
public void Dispose ()
{
if (frames != null) {
foreach (var f in frames)
f.Dispose ();
}
}
public Size DefaultSize {
get {
if (frames != null)
return new Size (frames[0].Width, frames[0].Height);
else
return Size.Zero;
}
}
public bool HasMultipleSizes {
get { return frames != null && frames.Length > 1 || drawCallback != null || stockId != null; }
}
Gdk.Pixbuf FindFrame (int width, int height)
{
if (frames == null)
return null;
if (frames.Length == 1)
return frames [0];
Gdk.Pixbuf best = null;
int bestSize = 0;
foreach (var p in frames) {
var s = p.Width * p.Height;
if (best == null || (p.Width <= width && p.Height <= height && s > bestSize)) {
best = p;
bestSize = s;
}
}
return best;
}
public Gdk.Pixbuf GetBestFrame (ApplicationContext actx, Gtk.Widget w, double width, double height, bool forceExactSize)
{
return GetBestFrame (actx, Util.GetScaleFactor (w), width, height, forceExactSize);
}
public Gdk.Pixbuf GetBestFrame (ApplicationContext actx, double scaleFactor, double width, double height, bool forceExactSize)
{
var f = FindFrame ((int)(width * scaleFactor), (int)(height * scaleFactor));
if (f == null || (forceExactSize && (f.Width != (int)width || f.Height != (int)height)))
return RenderFrame (actx, scaleFactor, width, height);
else
return f;
}
Gdk.Pixbuf RenderFrame (ApplicationContext actx, double scaleFactor, double width, double height)
{
var sf = new Cairo.ImageSurface (Cairo.Format.ARGB32, (int)(width * scaleFactor), (int)(height * scaleFactor));
var ctx = new Cairo.Context (sf);
ImageDescription idesc = new ImageDescription () {
Alpha = 1,
Size = new Size (width * scaleFactor, height * scaleFactor)
};
Draw (actx, ctx, 1, 0, 0, idesc);
var f = ImageBuilderBackend.CreatePixbuf (sf);
AddFrame (f);
return f;
}
void AddFrame (Gdk.Pixbuf pix)
{
if (frames == null)
frames = new Gdk.Pixbuf[] { pix };
else if (!frames.Contains (pix)) {
Array.Resize (ref frames, frames.Length + 1);
frames [frames.Length - 1] = pix;
}
}
public void Draw (ApplicationContext actx, Cairo.Context ctx, double scaleFactor, double x, double y, ImageDescription idesc)
{
if (stockId != null) {
Gdk.Pixbuf img = null;
if (frames != null)
img = frames.FirstOrDefault (p => p.Width == (int) idesc.Size.Width && p.Height == (int) idesc.Size.Height);
if (img == null) {
img = ImageHandler.CreateBitmap (stockId, idesc.Size.Width, idesc.Size.Height);
AddFrame (img);
}
DrawPixbuf (ctx, img, x, y, idesc);
}
else if (drawCallback != null) {
CairoContextBackend c = new CairoContextBackend (scaleFactor) {
Context = ctx
};
actx.InvokeUserCode (delegate {
drawCallback (c, new Rectangle (x, y, idesc.Size.Width, idesc.Size.Height));
});
}
else {
DrawPixbuf (ctx, GetBestFrame (actx, scaleFactor, idesc.Size.Width, idesc.Size.Height, false), x, y, idesc);
}
}
void DrawPixbuf (Cairo.Context ctx, Gdk.Pixbuf img, double x, double y, ImageDescription idesc)
{
ctx.Save ();
ctx.Translate (x, y);
ctx.Scale (idesc.Size.Width / (double)img.Width, idesc.Size.Height / (double)img.Height);
Gdk.CairoHelper.SetSourcePixbuf (ctx, img, 0, 0);
if (idesc.Alpha == 1)
ctx.Paint ();
else
ctx.PaintWithAlpha (idesc.Alpha);
ctx.Restore ();
}
}
public class ImageBox: Gtk.DrawingArea
{
ImageDescription image;
ApplicationContext actx;
float yalign = 0.5f, xalign = 0.5f;
public ImageBox (ApplicationContext actx, ImageDescription img): this (actx)
{
Image = img;
}
public ImageBox (ApplicationContext actx)
{
WidgetFlags |= Gtk.WidgetFlags.AppPaintable;
WidgetFlags |= Gtk.WidgetFlags.NoWindow;
this.actx = actx;
}
public ImageDescription Image {
get { return image; }
set { image = value; QueueResize (); }
}
public float Yalign {
get { return yalign; }
set { yalign = value; QueueDraw (); }
}
public float Xalign {
get { return xalign; }
set { xalign = value; QueueDraw (); }
}
protected override void OnSizeRequested (ref Gtk.Requisition requisition)
{
base.OnSizeRequested (ref requisition);
if (!image.IsNull) {
requisition.Width = (int) image.Size.Width;
requisition.Height = (int) image.Size.Height;
}
}
protected override bool OnExposeEvent (Gdk.EventExpose evnt)
{
if (image.IsNull)
return true;
int x = Allocation.X + (int)(((float)Allocation.Width - (float)image.Size.Width) * xalign);
int y = Allocation.Y + (int)(((float)Allocation.Height - (float)image.Size.Height) * yalign);
if (x < 0) x = 0;
if (y < 0) y = 0;
using (var ctx = Gdk.CairoHelper.Create (GdkWindow)) {
((GtkImage)image.Backend).Draw (actx, ctx, Util.GetScaleFactor (this), x, y, image);
return true;
}
}
}
}

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

@ -31,26 +31,56 @@ namespace Xwt.GtkBackend
public class GtkImagePatternBackendHandler: ImagePatternBackendHandler
{
#region IImagePatternBackendHandler implementation
public override object Create (object img)
public override object Create (ImageDescription img)
{
Gdk.Pixbuf pb = (Gdk.Pixbuf)img;
var imgs = new Cairo.ImageSurface (Cairo.Format.ARGB32, pb.Width, pb.Height);
var ic = new Cairo.Context (imgs);
Gdk.CairoHelper.SetSourcePixbuf (ic, pb, 0, 0);
ic.Paint ();
imgs.Flush ();
((IDisposable)ic).Dispose ();
var p = new Cairo.SurfacePattern (imgs);
p.Extend = Cairo.Extend.Repeat;
return p;
return new ImagePatternBackend () {
Image = img
};
}
public override void Dispose (object img)
{
Gdk.Pixbuf pb = (Gdk.Pixbuf)img;
var pb = (ImagePatternBackend)img;
pb.Dispose ();
}
#endregion
}
class ImagePatternBackend
{
public ImageDescription Image;
Cairo.SurfacePattern pattern;
double currentScaleFactor;
public Cairo.Pattern GetPattern (ApplicationContext actx, double scaleFactor)
{
if (pattern == null || currentScaleFactor != scaleFactor) {
if (pattern != null)
pattern.Dispose ();
Gdk.Pixbuf pb = ((GtkImage)Image.Backend).GetBestFrame (actx, scaleFactor, Image.Size.Width, Image.Size.Height, false);
var imgs = new Cairo.ImageSurface (Cairo.Format.ARGB32, (int)(Image.Size.Width * scaleFactor), (int)(Image.Size.Height * scaleFactor));
var ic = new Cairo.Context (imgs);
ic.Scale ((double)imgs.Width / (double)pb.Width, (double)imgs.Height / (double)pb.Height);
Gdk.CairoHelper.SetSourcePixbuf (ic, pb, 0, 0);
ic.Paint ();
imgs.Flush ();
((IDisposable)ic).Dispose ();
pattern = new Cairo.SurfacePattern (imgs);
pattern.Extend = Cairo.Extend.Repeat;
var cm = new Cairo.Matrix ();
cm.Scale (scaleFactor, scaleFactor);
pattern.Matrix = cm;
currentScaleFactor = scaleFactor;
}
return pattern;
}
public void Dispose ()
{
if (pattern != null)
pattern.Dispose ();
}
}
}

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

@ -34,32 +34,18 @@ namespace Xwt.GtkBackend
{
public override void Initialize ()
{
Widget = new Gtk.Image ();
Widget = new ImageBox (ApplicationContext);
Widget.Show ();
}
protected new Gtk.Image Widget {
get { return (Gtk.Image)base.Widget; }
protected new ImageBox Widget {
get { return (ImageBox)base.Widget; }
set { base.Widget = value; }
}
public void SetImage (Image image)
public void SetImage (ImageDescription image)
{
if (image == null) {
Widget.Pixbuf = null;
return;
}
Gdk.Pixbuf pbuf = Toolkit.GetBackend (image) as Gdk.Pixbuf;
if (pbuf == null)
pbuf = Toolkit.GetBackend (image.ToBitmap ()) as Gdk.Pixbuf;
if (pbuf == null)
throw new ArgumentException ("image is not of the expected type", "image");
if (image.HasFixedSize && (pbuf.Width != (int)image.Size.Width || pbuf.Height != (int)image.Size.Height))
pbuf = pbuf.ScaleSimple ((int)image.Size.Width, (int)image.Size.Height, Gdk.InterpType.Bilinear);
Widget.Pixbuf = pbuf;
Widget.Image = image;
}
}
}

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

@ -58,7 +58,7 @@ namespace Xwt.GtkBackend
{
theColumn.Clear ();
foreach (var v in views)
CellUtil.CreateCellRenderer (this, theColumn, v, Widget.Model);
CellUtil.CreateCellRenderer (ApplicationContext, this, theColumn, v, Widget.Model);
}
public override void EnableEvent (object eventId)

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

@ -72,13 +72,13 @@ namespace Xwt.GtkBackend
}
}
public void SetImage (object imageBackend)
public void SetImage (ImageDescription image)
{
Gtk.ImageMenuItem it = item as Gtk.ImageMenuItem;
if (it == null)
return;
if (imageBackend != null) {
var img = new Gtk.Image ((Gdk.Pixbuf) imageBackend);
if (!image.IsNull) {
var img = new ImageBox (context, image);
img.ShowAll ();
it.Image = img;
GtkWorkarounds.ForceImageOnMenuItem (it);

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

@ -35,20 +35,20 @@ namespace Xwt.GtkBackend
{
Gtk.StatusIcon statusItem;
MenuBackend menu;
public void SetImage (object imageBackend)
{
if (imageBackend == null) {
throw new ArgumentNullException ("imageBackend");
}
statusItem.Pixbuf = (Pixbuf)imageBackend;
}
ApplicationContext context;
public void InitializeBackend (object frontend, ApplicationContext context)
{
this.context = context;
statusItem = new Gtk.StatusIcon();
}
public void SetImage (ImageDescription image)
{
image = image.WithDefaultSize (Gtk.IconSize.Menu);
statusItem.Pixbuf = ((GtkImage)image.Backend).GetBestFrame (context, Util.GetDefaultScaleFactor (), image.Size.Width, image.Size.Height, true);
}
public void SetMenu (object menuBackend)
{
if (menuBackend == null) {

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

@ -52,7 +52,7 @@ namespace Xwt.GtkBackend
types = new Type[columnTypes.Length];
for (int n=0; n<types.Length; n++) {
if (columnTypes [n] == typeof(Image))
types [n] = typeof(Gdk.Pixbuf);
types [n] = typeof(ImageDescription);
else if (columnTypes [n] == typeof(Object))
types [n] = typeof(ObjectWrapper);
else
@ -75,7 +75,7 @@ namespace Xwt.GtkBackend
else if (value is string)
store.SetValue (it, column, (string)value);
else if (value is Image)
store.SetValue (it, column, ((Image)value).ToPixbuf (Gtk.IconSize.Menu));
store.SetValue (it, column, ToolkitEngineBackend.GetImageDescription((Image)value).WithDefaultSize (Gtk.IconSize.Menu));
else
store.SetValue (it, column, value ?? DBNull.Value);
}

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

@ -119,13 +119,13 @@ namespace Xwt.GtkBackend
if (col.HeaderView == null)
tc.Title = col.Title;
else
tc.Widget = CellUtil.CreateCellRenderer (col.HeaderView);
tc.Widget = CellUtil.CreateCellRenderer (ApplicationContext, col.HeaderView);
}
void MapColumn (ListViewColumn col, Gtk.TreeViewColumn tc)
{
foreach (var v in col.Views) {
CellUtil.CreateCellRenderer (this, tc, v, Widget.Model);
CellUtil.CreateCellRenderer (ApplicationContext, this, tc, v, Widget.Model);
}
}

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

@ -65,8 +65,10 @@ namespace Xwt.GtkBackend
return;
if (val is string)
data.Text = (string)val;
else if (val is Xwt.Drawing.Image)
data.SetPixbuf ((Gdk.Pixbuf) Toolkit.GetBackend (val));
else if (val is Xwt.Drawing.Image) {
var bmp = ((Image)val).ToBitmap ();
data.SetPixbuf (((GtkImage)Toolkit.GetBackend (bmp)).Frames[0]);
}
else {
var at = Gdk.Atom.Intern (atomType, false);
data.Set (at, 0, TransferDataSource.SerializeValue (val));
@ -163,7 +165,7 @@ namespace Xwt.GtkBackend
static Dictionary<string,string> icons;
public static string ToGtkStock (string id)
public static GtkImage ToGtkStock (string id)
{
if (icons == null) {
icons = new Dictionary<string, string> ();
@ -180,8 +182,9 @@ namespace Xwt.GtkBackend
icons [StockIconId.Information] = Gtk.Stock.DialogInfo;
}
string res;
icons.TryGetValue (id, out res);
return res;
if (!icons.TryGetValue (id, out res))
throw new NotSupportedException ("Unknown image: " + id);
return new GtkImage (res);
}
public static Gtk.IconSize ToGtkSize (Xwt.IconSize size)
@ -280,15 +283,24 @@ namespace Xwt.GtkBackend
return iconSizes [(int)s].Width;
}
public static Gdk.Pixbuf ToPixbuf (this Image image, Gtk.IconSize defaultIconSize)
public static ImageDescription WithDefaultSize (this ImageDescription image, Gtk.IconSize defaultIconSize)
{
if (!image.HasFixedSize) {
if (image.Size.IsZero) {
var s = iconSizes [(int)defaultIconSize];
image = image.WithSize (s.Width, s.Height);
image.Size = s;
}
return (Gdk.Pixbuf)Toolkit.GetBackend (image.ToBitmap ());
return image;
}
public static double GetScaleFactor (Gtk.Widget w)
{
return 1;
}
public static double GetDefaultScaleFactor ()
{
return 1;
}
}
}

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

@ -1050,8 +1050,10 @@ namespace Xwt.GtkBackend
DragDropInfo.CurrentDragData = sdata.Data;
if (sdata.ImageBackend != null)
Gtk.Drag.SetIconPixbuf (args.Context, (Gdk.Pixbuf) sdata.ImageBackend, (int)sdata.HotX, (int)sdata.HotY);
if (sdata.ImageBackend != null) {
var img = ((GtkImage)sdata.ImageBackend).GetBestFrame (ApplicationContext, Widget, 24, 24, true);
Gtk.Drag.SetIconPixbuf (args.Context, img, (int)sdata.HotX, (int)sdata.HotY);
}
HandleDragBegin (null, args);
}
@ -1085,8 +1087,10 @@ namespace Xwt.GtkBackend
Gdk.DragAction action = ConvertDragAction (sdata.DragAction);
DragDropInfo.CurrentDragData = sdata.Data;
EventsRootWidget.DragBegin += HandleDragBegin;
if (sdata.ImageBackend != null)
IconInitializer.Init (EventsRootWidget, (Gdk.Pixbuf) sdata.ImageBackend, sdata.HotX, sdata.HotY);
if (sdata.ImageBackend != null) {
var img = ((GtkImage)sdata.ImageBackend).GetBestFrame (ApplicationContext, Widget, 24, 24, true);
IconInitializer.Init (EventsRootWidget, img, sdata.HotX, sdata.HotY);
}
Gtk.Drag.Begin (EventsRootWidget, Util.BuildTargetTable (sdata.Data.DataTypes), action, 1, Gtk.Global.CurrentEvent ?? new Gdk.Event (IntPtr.Zero));
}

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

@ -196,9 +196,15 @@ namespace Xwt.GtkBackend
}
}
public void SetIcon(object backendImage)
object IWindowFrameBackend.Screen {
get {
return Window.Screen.GetMonitorAtWindow (Window.GdkWindow);
}
}
public void SetIcon(ImageDescription icon)
{
Window.Icon = backendImage as Gdk.Pixbuf;
// TODO
}
#endregion

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

@ -129,14 +129,6 @@
<Folder Include="Xwt.Mac.CellViews\" />
<Folder Include="icons\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="icons\magnifier-zoom-in.png">
<LogicalName>magnifier-zoom-in.png</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="icons\magnifier-zoom-out.png">
<LogicalName>magnifier-zoom-out.png</LogicalName>
</EmbeddedResource>
</ItemGroup>
<ProjectExtensions>
<MonoDevelop>
<Properties>
@ -146,4 +138,18 @@
</Properties>
</MonoDevelop>
</ProjectExtensions>
<ItemGroup>
<EmbeddedResource Include="icons\zoom-in.png">
<LogicalName>zoom-in.png</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="icons\zoom-in%402x.png">
<LogicalName>zoom-in@2x.png</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="icons\zoom-out.png">
<LogicalName>zoom-out.png</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="icons\zoom-out%402x.png">
<LogicalName>zoom-out@2x.png</LogicalName>
</EmbeddedResource>
</ItemGroup>
</Project>

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

@ -42,6 +42,10 @@ namespace Xwt.Mac
{
}
public void Initialize (ApplicationContext actx)
{
}
#region IAlertDialogBackend implementation
public Command Run (WindowFrame transientFor, MessageDescription message)
{

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

@ -56,14 +56,14 @@ namespace Xwt.Mac
((MacButton)Widget).DisableEvent (ev);
}
public void SetContent (string label, Image image, ContentPosition imagePosition)
public void SetContent (string label, ImageDescription image, ContentPosition imagePosition)
{
Widget.Title = label ?? "";
if (string.IsNullOrEmpty (label))
imagePosition = ContentPosition.Center;
if (image != null) {
var imageBackend = Toolkit.GetBackend (image.ToBitmap ());
Widget.Image = (NSImage)imageBackend;
if (!image.IsNull) {
var img = image.ToNSImage ();
Widget.Image = (NSImage)img;
switch (imagePosition) {
case ContentPosition.Bottom: Widget.ImagePosition = NSCellImagePosition.ImageBelow; break;
case ContentPosition.Left: Widget.ImagePosition = NSCellImagePosition.ImageLeft; break;

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

@ -239,10 +239,22 @@ namespace Xwt.Mac
if (gc.CurrentStatus.Pattern is ImagePatternInfo) {
var pi = (ImagePatternInfo) gc.CurrentStatus.Pattern;
RectangleF bounds = new RectangleF (PointF.Empty, new SizeF (pi.Image.Width, pi.Image.Height));
RectangleF bounds = new RectangleF (PointF.Empty, new SizeF (pi.Image.Size.Width, pi.Image.Size.Height));
var t = CGAffineTransform.Multiply (CGAffineTransform.MakeScale (1f, -1f), gc.Context.GetCTM ());
var pattern = new CGPattern (bounds, t, bounds.Width, bounds.Height,
CGPatternTiling.ConstantSpacing, true, c => c.DrawImage (bounds, pi.Image));
CGPattern pattern;
if (pi.Image is CustomImage) {
pattern = new CGPattern (bounds, t, bounds.Width, bounds.Height, CGPatternTiling.ConstantSpacing, true, c => {
c.TranslateCTM (0, bounds.Height);
c.ScaleCTM (1f, -1f);
((CustomImage)pi.Image).DrawInContext (c);
});
} else {
RectangleF empty = RectangleF.Empty;
CGImage cgimg = ((NSImage)pi.Image).AsCGImage (ref empty, null, null);
pattern = new CGPattern (bounds, CGAffineTransform.MakeScale (1f, -1f), bounds.Width, bounds.Height,
CGPatternTiling.ConstantSpacing, true, c => c.DrawImage (bounds, cgimg));
}
CGContext ctx = gc.Context;
float[] alpha = new[] { 1.0f };
@ -265,29 +277,35 @@ namespace Xwt.Mac
MacTextLayoutBackendHandler.Draw (ctx, Toolkit.GetBackend (layout), x, y);
}
public override bool CanDrawImage (object backend, object img)
public override void DrawImage (object backend, ImageDescription img, double x, double y)
{
return img is NSImage;
var srcRect = new Rectangle (Point.Zero, img.Size);
var destRect = new Rectangle (x, y, img.Size.Width, img.Size.Height);
DrawImage (backend, img, srcRect, destRect);
}
public override void DrawImage (object backend, object img, double x, double y, double width, double height, double alpha)
{
var srcRect = new Rectangle (Point.Zero, ((NSImage)img).Size.ToXwtSize ());
var destRect = new Rectangle (x, y, width, height);
DrawImage (backend, img, srcRect, destRect, width, height, alpha);
}
public override void DrawImage (object backend, object img, Rectangle srcRect, Rectangle destRect, double width, double height, double alpha)
public override void DrawImage (object backend, ImageDescription img, Rectangle srcRect, Rectangle destRect)
{
CGContext ctx = ((CGContextBackend)backend).Context;
NSImage image = (NSImage) img;
var rect = new RectangleF (0, 0, (float)destRect.Width, (float)destRect.Height);
NSImage image = img.ToNSImage ();
ctx.SaveState ();
ctx.SetAlpha ((float)alpha);
ctx.TranslateCTM ((float)destRect.X, (float)destRect.Y + rect.Height);
ctx.SetAlpha ((float)img.Alpha);
double rx = destRect.Width / srcRect.Width;
double ry = destRect.Height / srcRect.Height;
ctx.AddRect (new RectangleF ((float)destRect.X, (float)destRect.Y, (float)destRect.Width, (float)destRect.Height));
ctx.Clip ();
ctx.TranslateCTM ((float)(destRect.X - (srcRect.X * rx)), (float)(destRect.Y - (srcRect.Y * ry)));
ctx.ScaleCTM ((float)rx, (float)ry);
if (image is CustomImage) {
((CustomImage)image).DrawInContext ((CGContextBackend)backend);
} else {
RectangleF rr = new RectangleF (0, 0, (float)image.Size.Width, image.Size.Height);
ctx.ScaleCTM (1f, -1f);
RectangleF rr = RectangleF.Empty;
ctx.DrawImage (rect, image.AsCGImage (ref rr, null, null).WithImageInRect (srcRect.ToRectangleF ()));
ctx.DrawImage (new RectangleF (0, -image.Size.Height, image.Size.Width, image.Size.Height), image.AsCGImage (ref rr, NSGraphicsContext.CurrentContext, null));
}
ctx.RestoreState ();
}

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

@ -34,7 +34,7 @@ namespace Xwt.Mac
{
public class MacFontBackendHandler: FontBackendHandler
{
public override object Create (string fontName, double size, FontSizeUnit sizeUnit, FontStyle style, FontWeight weight, FontStretch stretch)
public override object Create (string fontName, double size, FontStyle style, FontWeight weight, FontStretch stretch)
{
object o = NSFont.FromFontName (fontName, (float)size);
return o;
@ -47,7 +47,7 @@ namespace Xwt.Mac
return (NSFont)f.Copy ();
}
public override object SetSize (object handle, double size, FontSizeUnit sizeUnit)
public override object SetSize (object handle, double size)
{
NSFont f = (NSFont) handle;
return NSFontManager.SharedFontManager.ConvertFont (f, (float)size);

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

@ -35,6 +35,7 @@ using System.Collections.Generic;
using System.Runtime.InteropServices;
using Xwt.Drawing;
using System.IO;
using MonoMac.CoreGraphics;
namespace Xwt.Mac
{
@ -59,6 +60,19 @@ namespace Xwt.Mac
return new NSImage (file);
}
public override object CreateMultiSizeImage (IEnumerable<object> images)
{
NSImage res = new NSImage ();
foreach (NSImage img in images)
res.AddRepresentations (img.Representations ());
return res;
}
public override object CreateCustomDrawn (ImageDrawCallback drawCallback)
{
return new CustomImage (ApplicationContext, drawCallback);
}
public override Xwt.Drawing.Image GetStockIcon (string id)
{
NSImage img;
@ -90,8 +104,47 @@ namespace Xwt.Mac
return img != null && img.Representations ().OfType<NSBitmapImageRep> ().Any ();
}
public override object ConvertToBitmap (object handle, double width, double height)
public override object ConvertToBitmap (object handle, int pixelWidth, int pixelHeight, ImageFormat format)
{
if (handle is CustomImage) {
var flags = CGBitmapFlags.ByteOrderDefault;
int bytesPerRow;
switch (format) {
case ImageFormat.ARGB32:
bytesPerRow = pixelWidth * 4;
flags |= CGBitmapFlags.PremultipliedFirst;
break;
case ImageFormat.RGB24:
bytesPerRow = pixelWidth * 3;
flags |= CGBitmapFlags.None;
break;
default:
throw new NotImplementedException ("ImageFormat: " + format.ToString ());
}
var bmp = new CGBitmapContext (IntPtr.Zero, pixelWidth, pixelHeight, 8, bytesPerRow, Util.DeviceRGBColorSpace, flags);
bmp.TranslateCTM (0, pixelHeight);
bmp.ScaleCTM (1, -1);
var ctx = new CGContextBackend {
Context = bmp,
Size = new SizeF (pixelWidth, pixelHeight),
InverseViewTransform = bmp.GetCTM ().Invert ()
};
var ci = (CustomImage)handle;
ci.DrawInContext (ctx);
var img = new NSImage (((CGBitmapContext)bmp).ToImage (), new SizeF (pixelWidth, pixelHeight));
var imageData = img.AsTiff ();
var imageRep = (NSBitmapImageRep) NSBitmapImageRep.ImageRepFromData (imageData);
var im = new NSImage ();
im.AddRepresentation (imageRep);
return im;
}
else
return handle;
}
@ -127,13 +180,6 @@ namespace Xwt.Mac
return new Size ((int)img.Size.Width, (int)img.Size.Height);
}
public override object ResizeBitmap (object handle, double width, double height)
{
NSImage newImg = (NSImage)CopyBitmap (handle);
newImg.Size = new SizeF ((float)width, (float)height);
return newImg;
}
public override object CopyBitmap (object handle)
{
return ((NSImage)handle).Copy ();
@ -149,19 +195,6 @@ namespace Xwt.Mac
throw new NotImplementedException ();
}
public override object ChangeBitmapOpacity (object backend, double opacity)
{
//http://stackoverflow.com/a/2868928/578190
NSImage img = (NSImage)backend;
NSImage newImg = new NSImage (img.Size);
newImg.LockFocus ();
img.Draw (PointF.Empty, RectangleF.Empty, NSCompositingOperation.SourceOver, (float)opacity);
newImg.UnlockFocus ();
return newImg;
}
static NSImage FromResource (string res)
{
var stream = typeof(ImageHandler).Assembly.GetManifestResourceStream (res);
@ -171,15 +204,19 @@ namespace Xwt.Mac
}
}
static NSImage LoadStockIcon (string id)
static NSImage NSImageFromResource (string id)
{
NSImage image = null;
switch (id) {
case StockIconId.ZoomIn: image = FromResource ("magnifier-zoom-in.png"); break;
case StockIconId.ZoomOut: image = FromResource ("magnifier-zoom-out.png"); break;
return (NSImage) Toolkit.GetBackend (Xwt.Drawing.Image.FromResource (typeof(ImageHandler), id));
}
static NSImage LoadStockIcon (string id)
{
switch (id) {
case StockIconId.ZoomIn: return NSImageFromResource ("zoom-in.png");
case StockIconId.ZoomOut: return NSImageFromResource ("zoom-out.png");
}
NSImage image = null;
IntPtr iconRef;
var type = Util.ToIconType (id);
if (type != 0 && GetIconRef (-32768/*kOnSystemDisk*/, 1835098995/*kSystemIconsCreator*/, type, out iconRef) == 0) {
@ -200,5 +237,55 @@ namespace Xwt.Mac
[DllImport ("/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/LaunchServices")]
static extern int ReleaseIconRef (IntPtr iconRef);
}
public class CustomImage: NSImage
{
ImageDrawCallback drawCallback;
ApplicationContext actx;
NSCustomImageRep imgRep;
public CustomImage (ApplicationContext actx, ImageDrawCallback drawCallback)
{
this.actx = actx;
this.drawCallback = drawCallback;
imgRep = new NSCustomImageRep (new Selector ("drawIt:"), this);
AddRepresentation (imgRep);
}
[Export ("drawIt:")]
public void DrawIt (NSObject ob)
{
CGContext ctx = NSGraphicsContext.CurrentContext.GraphicsPort;
DrawInContext (ctx);
}
internal void DrawInContext (CGContext ctx)
{
var backend = new CGContextBackend {
Context = ctx,
InverseViewTransform = ctx.GetCTM ().Invert ()
};
DrawInContext (backend);
}
internal void DrawInContext (CGContextBackend ctx)
{
var s = ctx.Size != SizeF.Empty ? ctx.Size : Size;
actx.InvokeUserCode (delegate {
drawCallback (ctx, new Rectangle (0, 0, s.Width, s.Height));
});
}
public override CGImage AsCGImage (ref RectangleF proposedDestRect, NSGraphicsContext referenceContext, NSDictionary hints)
{
return base.AsCGImage (ref proposedDestRect, referenceContext, hints);
}
public CustomImage Clone ()
{
return new CustomImage (actx, drawCallback);
}
}
}

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

@ -33,13 +33,11 @@ namespace Xwt.Mac
{
public class MacImagePatternBackendHandler: ImagePatternBackendHandler
{
public override object Create (object img)
public override object Create (ImageDescription img)
{
NSImage nimg = (NSImage) img;
RectangleF empty = RectangleF.Empty;
CGImage cgimg = nimg.AsCGImage (ref empty, null, null);
NSImage nimg = img.ToNSImage ();
return new ImagePatternInfo () {
Image = cgimg
Image = nimg
};
}
@ -50,7 +48,7 @@ namespace Xwt.Mac
class ImagePatternInfo
{
public CGImage Image;
public NSImage Image;
}
}

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

@ -48,20 +48,14 @@ namespace Xwt.Mac
return img == null ? Size.Zero : img.Size.ToXwtSize ();
}
public void SetImage (Image image)
public void SetImage (ImageDescription image)
{
if (image == null) {
if (image.IsNull) {
Widget.Image = null;
return;
}
NSImage nativeImage = Toolkit.GetBackend (image) as NSImage;
if (nativeImage == null)
nativeImage = Toolkit.GetBackend (image.ToBitmap ()) as NSImage;
if (nativeImage == null)
throw new ArgumentException ("nativeImage is not of the expected type", "nativeImage");
Widget.Image = nativeImage;
Widget.Image = image.ToNSImage ();
Widget.SetFrameSize (Widget.Image.Size);
}
}

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

@ -74,10 +74,9 @@ namespace Xwt.Mac
}
}
public void SetImage (object imageBackend)
public void SetImage (ImageDescription image)
{
var img = (NSImage) imageBackend;
item.Image = img;
item.Image = image.ToNSImage ();
}
public bool Visible {

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

@ -53,12 +53,9 @@ namespace Xwt.Mac
statusItem.Menu = (NSMenu)menuBackend;
}
public void SetImage (object imageBackend) {
if (imageBackend == null) {
throw new ArgumentNullException ("imageBackend");
}
statusItem.Image = (NSImage)imageBackend;
public void SetImage (ImageDescription image)
{
statusItem.Image = image.ToNSImage ();
}
public void EnableEvent (object eventId) { throw new NotImplementedException (); }

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

@ -183,42 +183,36 @@ namespace Xwt.Mac
public override void SetForeground (object backend, Color color, int startIndex, int count)
{
throw new NotImplementedException ();
}
public override void SetBackgound (object backend, Color color, int startIndex, int count)
{
throw new NotImplementedException ();
}
public override void SetFontWeight (object backend, FontWeight weight, int startIndex, int count)
{
throw new NotImplementedException ();
}
public override void SetFontStyle (object backend, FontStyle style, int startIndex, int count)
{
throw new NotImplementedException ();
}
public override void SetUnderline (object backend, int startIndex, int count)
{
throw new NotImplementedException ();
}
public override void SetStrikethrough (object backend, int startIndex, int count)
{
throw new NotImplementedException ();
}
public override int GetIndexFromCoordinates (object backend, double x, double y)
{
throw new NotImplementedException ();
return 0;
}
public override Point GetCoordinateFromIndex (object backend, int index)
{
throw new NotImplementedException ();
return new Point (0,0);
}
public override void DisposeBackend (object backend)

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

@ -236,6 +236,18 @@ namespace Xwt.Mac
throw new NotSupportedException ();
}
}
public static NSImage ToNSImage (this ImageDescription idesc)
{
var img = (NSImage)idesc.Backend;
if (img is CustomImage)
img = ((CustomImage)img).Clone ();
else {
img = (NSImage)img.Copy ();
}
img.Size = new System.Drawing.SizeF ((float)idesc.Size.Width, (float)idesc.Size.Height);
return img;
}
}
public interface ICopiableObject

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

@ -151,6 +151,12 @@ namespace Xwt.Mac
}
}
object IWindowFrameBackend.Screen {
get {
return Screen;
}
}
protected virtual NSView GetContentView ()
{
return ContentView;
@ -412,7 +418,7 @@ namespace Xwt.Mac
MinSize = r.Size;
}
public void SetIcon (object imageBackend)
public void SetIcon (ImageDescription icon)
{
}

Двоичные данные
Xwt.Mac/icons/magnifier-zoom-in.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 758 B

Двоичные данные
Xwt.Mac/icons/magnifier-zoom-out.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 736 B

Двоичные данные
Xwt.Mac/icons/zoom-in.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 715 B

Двоичные данные
Xwt.Mac/icons/zoom-in@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.0 KiB

Двоичные данные
Xwt.Mac/icons/zoom-out.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 707 B

Двоичные данные
Xwt.Mac/icons/zoom-out@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.9 KiB

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

@ -66,14 +66,14 @@ namespace Xwt.WPFBackend.Utilities
ImageCellView imageView = view as ImageCellView;
if (imageView != null) {
FrameworkElementFactory factory = new FrameworkElementFactory (typeof (SWC.Image));
FrameworkElementFactory factory = new FrameworkElementFactory (typeof (ImageBox));
factory.SetValue (FrameworkElement.MarginProperty, CellMargins);
if (imageView.ImageField != null) {
var binding = new Binding (dataPath + "[" + imageView.ImageField.Index + "]")
{ Converter = new ImageToImageSourceConverter () };
factory.SetBinding (SWC.Image.SourceProperty, binding);
factory.SetBinding (ImageBox.ImageSourceProperty, binding);
}
return factory;

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

@ -28,6 +28,7 @@ using System;
using System.Globalization;
using System.Windows.Data;
using Xwt.Drawing;
using Xwt.Backends;
namespace Xwt.WPFBackend.Utilities
@ -41,7 +42,7 @@ namespace Xwt.WPFBackend.Utilities
if (image == null)
return null;
return DataConverter.AsImageSource (Toolkit.GetBackend (image));
return ToolkitEngineBackend.GetImageDescription (image);
}
public object ConvertBack (object value, Type targetType, object parameter, CultureInfo culture)

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

@ -48,6 +48,10 @@ namespace Xwt.WPFBackend
this.defaultResult = MessageBoxResult.Cancel;
}
public void Initialize (ApplicationContext actx)
{
}
public Command Run (WindowFrame transientFor, MessageDescription message)
{
this.icon = GetIcon (message.Icon);
@ -77,21 +81,18 @@ namespace Xwt.WPFBackend
set;
}
MessageBoxImage GetIcon (string iconText)
MessageBoxImage GetIcon (Xwt.Drawing.Image icon)
{
switch (iconText) {
case StockIconId.Error:
if (icon == Xwt.StockIcons.Error)
return MessageBoxImage.Error;
case StockIconId.Warning:
if (icon == Xwt.StockIcons.Warning)
return MessageBoxImage.Warning;
case StockIconId.Information:
if (icon == Xwt.StockIcons.Information)
return MessageBoxImage.Information;
case StockIconId.Question:
if (icon == Xwt.StockIcons.Question)
return MessageBoxImage.Question;
default:
return MessageBoxImage.None;
}
}
Command ConvertResultToCommand (MessageBoxResult dialogResult)
{

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

@ -95,22 +95,16 @@ namespace Xwt.WPFBackend
Button.InvalidateMeasure ();
}
public void SetContent (string label, Xwt.Drawing.Image image, ContentPosition position)
public void SetContent (string label, ImageDescription image, ContentPosition position)
{
if (image == null)
if (image.IsNull)
Button.Content = label;
else
{
var imageBackend = Toolkit.GetBackend (image.ToBitmap ());
SWC.DockPanel grid = new SWC.DockPanel ();
var img = DataConverter.AsImageSource (imageBackend);
SWC.Image imageCtrl = new SWC.Image
{
Source = img,
Width = img.Width,
Height = img.Height
};
var imageCtrl = new ImageBox (Context);
imageCtrl.ImageSource = image;
SWC.DockPanel.SetDock (imageCtrl, DataConverter.ToWpfDock (position));
grid.Children.Add (imageCtrl);

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

@ -33,7 +33,7 @@ namespace Xwt.WPFBackend
private void Render (System.Windows.Media.DrawingContext dc)
{
CanvasEventSink.OnDraw (new Xwt.WPFBackend.DrawingContext (Widget, dc), new Rectangle (0, 0, Widget.ActualWidth, Widget.ActualHeight));
CanvasEventSink.OnDraw (new Xwt.WPFBackend.DrawingContext (dc, Widget.GetScaleFactor ()), new Rectangle (0, 0, Widget.ActualWidth, Widget.ActualHeight));
}
public void QueueDraw ()

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

@ -240,6 +240,8 @@ namespace Xwt.WPFBackend
public override void SetPattern (object backend, object p)
{
var c = (DrawingContext) backend;
if (p is ImagePattern)
p = ((ImagePattern)p).GetBrush (c.ScaleFactor);
c.SetPattern ((System.Windows.Media.Brush)p);
}
@ -255,23 +257,29 @@ namespace Xwt.WPFBackend
c.Context.DrawText (t.FormattedText, new SW.Point (x, y));
}
public override bool CanDrawImage (object backend, object img)
{
return true;
}
public override void DrawImage (object backend, object img, double x, double y, double width, double height, double alpha)
public override void DrawImage (object backend, ImageDescription img, double x, double y)
{
var c = (DrawingContext) backend;
ImageSource bmp = DataConverter.AsImageSource (img);
DrawImageCore (c.Context, bmp, x, y, width, height, alpha);
WpfImage bmp = (WpfImage) img.Backend;
bmp.Draw (ApplicationContext, c.Context, c.ScaleFactor, x, y, img);
}
public override void DrawImage (object backend, object img, Rectangle srcRect, Rectangle destRect, double width, double height, double alpha)
public override void DrawImage (object backend, ImageDescription img, Rectangle srcRect, Rectangle destRect)
{
var c = (DrawingContext) backend;
ImageSource bmp = DataConverter.AsImageSource (img);
DrawImageCore (c.Context, bmp, srcRect, destRect, alpha);
WpfImage bmp = (WpfImage)img.Backend;
c.Context.PushClip (new RectangleGeometry (destRect.ToWpfRect ()));
c.Context.PushTransform (new TranslateTransform (destRect.X - srcRect.X, destRect.Y - srcRect.Y));
var sw = destRect.Width / srcRect.Width;
var sh = destRect.Height / srcRect.Height;
c.Context.PushTransform (new ScaleTransform (sw, sh));
bmp.Draw (ApplicationContext, c.Context, c.ScaleFactor, 0, 0, img);
c.Context.Pop (); // Scale
c.Context.Pop (); // Translate
c.Context.Pop (); // Clip
}
public override void Rotate (object backend, double angle)
@ -333,35 +341,5 @@ namespace Xwt.WPFBackend
public override void Dispose (object backend)
{
}
internal static void DrawImageCore (SWM.DrawingContext g, ImageSource bmp, double x, double y, double width, double height, double alpha)
{
if (alpha < 1)
g.PushOpacity (alpha);
g.DrawImage (bmp, new Rect (x, y, width, height));
if (alpha < 1)
g.Pop ();
}
internal void DrawImageCore (SWM.DrawingContext g, ImageSource bmp, Rectangle srcRect, Rectangle destRect, double alpha)
{
if (alpha < 1)
g.PushOpacity (alpha);
g.PushClip (new RectangleGeometry (destRect.ToWpfRect ()));
var size = bmp is BitmapSource ? new Size (((BitmapSource)bmp).PixelWidth, ((BitmapSource)bmp).PixelHeight) : new Size (bmp.Width, bmp.Height);
var sw = destRect.Width / srcRect.Width;
var sh = destRect.Height / srcRect.Height;
g.DrawImage (bmp, new Rect (destRect.X - srcRect.X * sw, destRect.Y - srcRect.Y * sh, size.Width * sw, size.Height * sh));
g.Pop (); // Clip
if (alpha < 1)
g.Pop ();
}
}
}

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

@ -240,7 +240,12 @@ namespace Xwt.WPFBackend
public static SWM.ImageSource AsImageSource (object nativeImage)
{
var source = nativeImage as WpfImage;
return source.Image;
return source.Frames[0];
}
public static SWM.ImageSource ToImageSource (this Xwt.Backends.ImageDescription img)
{
return AsImageSource (img.Backend);
}
//

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

@ -46,11 +46,11 @@ namespace Xwt.WPFBackend
SWM.Brush patternBrush;
SWM.SolidColorBrush colorBrush;
public double ScaleFactor { get; set; }
public SW.Point LastFigureStart { get; set; }
public SW.Point EndPoint { get; set; }
public double PixelRatio { get; private set; }
public PathFigure Path { get; private set; }
public SWM.Pen Pen { get; private set; }
@ -78,12 +78,12 @@ namespace Xwt.WPFBackend
public System.Windows.Media.DrawingContext Context { get; private set; }
internal DrawingContext (Visual v, System.Windows.Media.DrawingContext dc)
internal DrawingContext (System.Windows.Media.DrawingContext dc, double scaleFactor)
{
Context = dc;
ScaleFactor = scaleFactor;
AllocatePen (Color.FromRgb (0, 0, 0), 1, DashStyles.Solid);
ResetPath ();
PixelRatio = v.GetPixelRatios ().Width;
}
internal DrawingContext (DrawingContext context)

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

@ -37,9 +37,13 @@ namespace Xwt.WPFBackend
{
public class WpfFontBackendHandler : FontBackendHandler
{
public override object Create (string fontName, double size, FontSizeUnit sizeUnit, FontStyle style, FontWeight weight, FontStretch stretch)
public override object Create (string fontName, double size, FontStyle style, FontWeight weight, FontStretch stretch)
{
return new FontData (new FontFamily (fontName), size, sizeUnit);
return new FontData (new FontFamily (fontName), size) {
Style = style.ToWpfFontStyle (),
Weight = weight.ToWpfFontWeight (),
Stretch = stretch.ToWpfFontStretch ()
};
}
public override object Copy (object handle)
@ -48,7 +52,7 @@ namespace Xwt.WPFBackend
return font.Clone ();
}
public override object SetSize (object handle, double size, FontSizeUnit sizeUnit)
public override object SetSize (object handle, double size)
{
var font = (FontData)handle;
font = font.Clone ();
@ -131,15 +135,14 @@ namespace Xwt.WPFBackend
internal class FontData
{
public FontData (FontFamily family, double size, FontSizeUnit unit)
public FontData (FontFamily family, double size)
{
Unit = unit;
Family = family;
Size = size;
}
public FontData (string family, double size, FontSizeUnit unit) :
this (new FontFamily (family), size, unit)
public FontData (string family, double size) :
this (new FontFamily (family), size)
{
}
@ -148,33 +151,22 @@ namespace Xwt.WPFBackend
public SW.FontWeight Weight { get; set; }
public SW.FontStyle Style { get; set; }
public SW.FontStretch Stretch { get; set; }
public FontSizeUnit Unit { get; set; }
public double GetDeviceIndependentPixelSize (SW.Controls.Control control)
{
if (Unit == FontSizeUnit.Points)
return WpfFontBackendHandler.GetDeviceUnitsFromPoints (Size);
else {
Size pixelRatios = control.GetPixelRatios ();
return Size / pixelRatios.Width;
}
}
public double GetDeviceIndependentPixelSize ()
{
if (Unit == FontSizeUnit.Points)
return WpfFontBackendHandler.GetDeviceUnitsFromPoints (Size);
else {
return Size;
}
}
public static FontData FromControl (SW.Controls.Control control)
{
Size pixelRatios = control.GetPixelRatios ();
var pixelSize = control.FontSize * pixelRatios.Width;
var pixelSize = control.FontSize;
return new FontData (control.FontFamily, pixelSize, FontSizeUnit.Pixels) {
return new FontData (control.FontFamily, pixelSize) {
Style = control.FontStyle,
Stretch = control.FontStretch,
Weight = control.FontWeight
@ -184,7 +176,7 @@ namespace Xwt.WPFBackend
// Didn't implement IClone on purpose (recommended by the Framework Design guidelines)
public FontData Clone ()
{
return new FontData (Family, Size, Unit) {
return new FontData (Family, Size) {
Style = Style,
Stretch = Stretch,
Weight = Weight

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

@ -52,7 +52,7 @@ namespace Xwt.WPFBackend
public override object CreateContext (object backend)
{
var visual = (ImageBuilder)backend;
visual.Context = new DrawingContext (visual, visual.RenderOpen ());
visual.Context = new DrawingContext (visual.RenderOpen (), visual.GetScaleFactor ());
return visual.Context;
}

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

@ -28,6 +28,7 @@
using System;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
@ -35,6 +36,7 @@ using Xwt.Backends;
using Xwt.WPFBackend.Interop;
using SWM = System.Windows.Media;
using SWMI = System.Windows.Media.Imaging;
using System.Collections.Generic;
namespace Xwt.WPFBackend
{
@ -68,6 +70,16 @@ namespace Xwt.WPFBackend
return BitmapSource.Create (width, height, dpi, dpi, bitmapImage.Format, null, pixelData, stride);
}
public override object CreateCustomDrawn (ImageDrawCallback drawCallback)
{
return new WpfImage (drawCallback);
}
public override object CreateMultiSizeImage (System.Collections.Generic.IEnumerable<object> images)
{
return new WpfImage (images.Cast<WpfImage> ().Select (i => i.Frames[0]));
}
public override void SaveToStream (object backend, Stream stream, Drawing.ImageFileType fileType)
{
var image = DataConverter.AsImageSource(backend) as BitmapSource;
@ -89,12 +101,7 @@ namespace Xwt.WPFBackend
var img3 = RenderStockIcon (id, NativeStockIconOptions.ShellSize);
var img4 = RenderStockIcon (id, default (NativeStockIconOptions));
return Xwt.Drawing.Image.FromMultipleSizes (
ApplicationContext.Toolkit.WrapImage (img1),
ApplicationContext.Toolkit.WrapImage (img2),
ApplicationContext.Toolkit.WrapImage (img3),
ApplicationContext.Toolkit.WrapImage (img4)
);
return ApplicationContext.Toolkit.WrapImage (CreateMultiSizeImage (new object[] { img1, img2, img3, img4 }));
}
object RenderStockIcon (string id, NativeStockIconOptions options)
@ -136,7 +143,7 @@ namespace Xwt.WPFBackend
public override Xwt.Drawing.Color GetBitmapPixel (object handle, int x, int y)
{
var wpfImage = (WpfImage)handle;
BitmapSource img = wpfImage.Image as BitmapSource;
BitmapSource img = wpfImage.Frames[0] as BitmapSource;
if (img == null)
throw new NotSupportedException ("Invalid image format");
if (img.Format.BitsPerPixel != 32)
@ -150,7 +157,7 @@ namespace Xwt.WPFBackend
public override void SetBitmapPixel (object handle, int x, int y, Drawing.Color color)
{
var wpfImage = (WpfImage)handle;
var img = (BitmapSource) wpfImage.Image;
var img = (BitmapSource) wpfImage.Frames[0];
if (img == null)
throw new NotSupportedException ("Invalid image format");
if (img.Format.BitsPerPixel != 32)
@ -160,7 +167,7 @@ namespace Xwt.WPFBackend
if (!(bitmapImage is WriteableBitmap)) {
bitmapImage = new WriteableBitmap (img);
((WpfImage)handle).Image = bitmapImage;
((WpfImage)handle).Frames[0] = bitmapImage;
}
wpfImage.AllocatePixelData ();
@ -205,9 +212,10 @@ namespace Xwt.WPFBackend
return img.Height;
}
public override object ConvertToBitmap (object handle, double width, double height)
public override object ConvertToBitmap (object img, int width, int height, Xwt.Drawing.ImageFormat format)
{
throw new NotImplementedException ();
var wpfImage = (WpfImage)img;
return new WpfImage (wpfImage.GetBestFrame (ApplicationContext, 1, width, height, true));
}
public override bool HasMultipleSizes (object handle)
@ -222,27 +230,8 @@ namespace Xwt.WPFBackend
public override Size GetSize (object handle)
{
BitmapSource source = (BitmapSource) DataConverter.AsImageSource (handle);
return new Size (source.PixelWidth, source.PixelHeight);
}
public override object ResizeBitmap (object handle, double width, double height)
{
var oldImg = (SWMI.BitmapSource)DataConverter.AsImageSource (handle);
width = WidthToDPI (oldImg, width);
height = HeightToDPI (oldImg, height);
SWM.DrawingVisual visual = new SWM.DrawingVisual ();
using (SWM.DrawingContext ctx = visual.RenderOpen ())
{
ctx.DrawImage (oldImg, new System.Windows.Rect (0, 0, width, height));
}
SWMI.RenderTargetBitmap bmp = new SWMI.RenderTargetBitmap ((int)width, (int)height, oldImg.DpiX, oldImg.DpiY, PixelFormats.Pbgra32);
bmp.Render (visual);
return new WpfImage (bmp);
var source = (WpfImage) handle;
return source.Size;
}
public override object CopyBitmap (object handle)
@ -270,19 +259,6 @@ namespace Xwt.WPFBackend
return bmp;
}
public override object ChangeBitmapOpacity (object backend, double opacity)
{
throw new System.NotImplementedException ();
/* Bitmap bitmap = DataConverter.AsBitmap (backend);
if (bitmap == null)
throw new ArgumentException ();
Bitmap result = new Bitmap (bitmap.Width, bitmap.Height, bitmap.PixelFormat);
Graphics g = Graphics.FromImage (result);
WpfContextBackendHandler.DrawImageCore (g, bitmap, 0, 0, bitmap.Width, bitmap.Height, (float)opacity);
g.Dispose ();
return result;
*/ }
public override void CopyBitmapArea (object srcHandle, int srcX, int srcY, int width, int height, object destHandle, int destX, int destY)
{
throw new NotImplementedException ();
@ -291,26 +267,58 @@ namespace Xwt.WPFBackend
class WpfImage
{
public WpfImage (ImageSource image)
{
Image = image;
}
ImageDrawCallback drawCallback;
public ImageSource Image;
public byte[] PixelData;
public int Stride;
public bool PixelWritePending;
List<ImageSource> frames = new List<ImageSource> ();
public WpfImage (ImageSource image)
{
if (image is BitmapFrame)
frames.AddRange (((BitmapFrame)image).Decoder.Frames);
else
frames.Add (image);
}
public WpfImage (IEnumerable<ImageSource> images)
{
frames.AddRange (images);
}
public WpfImage (ImageDrawCallback drawCallback)
{
this.drawCallback = drawCallback;
}
public List<ImageSource> Frames
{
get { return frames; }
}
public bool HasMultipleSizes
{
get { return frames != null && frames.Count > 1 || drawCallback != null; }
}
public Size Size {
get { return Frames.Count > 0 ? new Size (frames[0].Width, frames[0].Height) : Size.Zero; }
}
public int GetPixelOffset (int x, int y)
{
BitmapSource img = Image as BitmapSource;
if (frames.Count == 0)
throw new NotSupportedException ();
BitmapSource img = frames[0] as BitmapSource;
return y * Stride + x * ((img.Format.BitsPerPixel + 7) / 8);
}
public void AllocatePixelData ()
{
if (PixelData == null) {
BitmapSource img = Image as BitmapSource;
BitmapSource img = frames[0] as BitmapSource;
var height = (int) ImageHandler.HeightToPixels (img);
var width = (int) ImageHandler.WidthToPixels (img);
Stride = (width * img.Format.BitsPerPixel + 7) / 8;
@ -318,5 +326,129 @@ namespace Xwt.WPFBackend
img.CopyPixels (PixelData, Stride, 0);
}
}
ImageSource FindFrame (int width, int height)
{
if (frames == null)
return null;
if (frames.Count == 1)
return frames[0];
ImageSource bestSmall = null, bestBig = null;
double bestSmallSize = 0, bestBigSize = 0;
foreach (var p in frames) {
var s = p.Width * p.Height;
if (p.Width < width || p.Height < height) {
if (bestSmall == null || s > bestSmallSize) {
bestSmall = p;
bestSmallSize = s;
}
}
else {
if (bestBig == null || s < bestBigSize) {
bestBig = p;
bestBigSize = s;
}
}
}
return bestBig ?? bestSmall;
}
public ImageSource GetBestFrame (ApplicationContext actx, Visual w, double width, double height, bool forceExactSize)
{
return GetBestFrame (actx, w.GetScaleFactor (), width, height, forceExactSize);
}
public ImageSource GetBestFrame (ApplicationContext actx, double scaleFactor, double width, double height, bool forceExactSize)
{
var f = FindFrame ((int)(width * scaleFactor), (int)(height * scaleFactor));
if (f == null || (forceExactSize && (f.Width != (int)width || f.Height != (int)height)))
return RenderFrame (actx, scaleFactor, width, height);
else
return f;
}
ImageSource RenderFrame (ApplicationContext actx, double scaleFactor, double width, double height)
{
ImageDescription idesc = new ImageDescription () {
Alpha = 1,
Size = new Size (width * scaleFactor, height * scaleFactor)
};
SWM.DrawingVisual visual = new SWM.DrawingVisual ();
using (SWM.DrawingContext ctx = visual.RenderOpen ()) {
Draw (actx, ctx, 1, 0, 0, idesc);
}
SWMI.RenderTargetBitmap bmp = new SWMI.RenderTargetBitmap ((int)idesc.Size.Width, (int)idesc.Size.Height, 96, 96, PixelFormats.Pbgra32);
bmp.Render (visual);
AddFrame (bmp);
return bmp;
}
void AddFrame (ImageSource pix)
{
frames.Add (pix);
}
public void Draw (ApplicationContext actx, SWM.DrawingContext dc, double scaleFactor, double x, double y, ImageDescription idesc)
{
if (drawCallback != null) {
DrawingContext c = new DrawingContext (dc, scaleFactor);
actx.InvokeUserCode (delegate {
drawCallback (c, new Rectangle (x, y, idesc.Size.Width, idesc.Size.Height));
});
}
else {
if (idesc.Alpha < 1)
dc.PushOpacity (idesc.Alpha);
var f = GetBestFrame (actx, scaleFactor, idesc.Size.Width, idesc.Size.Height, false);
dc.DrawImage (f, new Rect (x, y, idesc.Size.Width, idesc.Size.Height));
if (idesc.Alpha < 1)
dc.Pop ();
}
}
}
public class ImageBox : System.Windows.Controls.Canvas
{
ApplicationContext actx;
public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register ("ImageSource", typeof (ImageDescription), typeof (ImageBox), new PropertyMetadata (ImageDescription.Null));
public ImageBox ()
{
this.actx = ToolkitEngineBackend.GetToolkitBackend<WPFEngine> ().ApplicationContext;
}
public ImageBox (ApplicationContext actx)
{
this.actx = actx;
}
protected override void OnRender (System.Windows.Media.DrawingContext dc)
{
var image = ImageSource;
if (!image.IsNull)
((WpfImage)image.Backend).Draw (actx, dc, this.GetScaleFactor (), 0, 0, image);
}
public ImageDescription ImageSource
{
get { return (ImageDescription)this.GetValue (ImageSourceProperty); }
set { SetValue (ImageSourceProperty, value); }
}
protected override System.Windows.Size MeasureOverride (System.Windows.Size constraint)
{
var image = ImageSource;
if (!image.IsNull)
return new System.Windows.Size (image.Size.Width, image.Size.Height);
else
return new System.Windows.Size (0, 0);
}
}
}

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

@ -33,21 +33,46 @@ namespace Xwt.WPFBackend
public class WpfImagePatternBackendHandler
: ImagePatternBackendHandler
{
public override object Create (object img)
public override object Create (ImageDescription img)
{
var bmp = DataConverter.AsImageSource (img);
return new ImageBrush (bmp) {
TileMode = TileMode.Tile,
ViewportUnits = BrushMappingMode.Absolute,
AlignmentY = System.Windows.Media.AlignmentY.Top,
AlignmentX = System.Windows.Media.AlignmentX.Left,
Stretch = System.Windows.Media.Stretch.None,
Viewport = new System.Windows.Rect (0, 0, bmp.Width, bmp.Height)
};
return new ImagePattern (ApplicationContext, img);
}
public override void Dispose (object img)
{
}
}
class ImagePattern
{
ApplicationContext actx;
ImageDescription image;
double scaleFactor;
ImageBrush brush;
public ImagePattern (ApplicationContext actx, ImageDescription im)
{
this.actx = actx;
this.image = im;
}
public ImageBrush GetBrush (double scaleFactor)
{
if (brush == null || scaleFactor != this.scaleFactor) {
this.scaleFactor = scaleFactor;
var ib = (WpfImage)image.Backend;
var bmp = ib.GetBestFrame (actx, scaleFactor, image.Size.Width, image.Size.Height, true);
brush = new ImageBrush (bmp) {
TileMode = TileMode.Tile,
ViewportUnits = BrushMappingMode.Absolute,
AlignmentY = System.Windows.Media.AlignmentY.Top,
AlignmentX = System.Windows.Media.AlignmentX.Left,
Stretch = System.Windows.Media.Stretch.None,
Viewport = new System.Windows.Rect (0, 0, image.Size.Width * scaleFactor, image.Size.Height * scaleFactor)
};
brush.RelativeTransform = new ScaleTransform (1d/scaleFactor, 1d/scaleFactor);
}
return brush;
}
}
}

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

@ -36,28 +36,22 @@ namespace Xwt.WPFBackend
{
public ImageViewBackend()
{
Widget = new Image ();
Image.Stretch = Stretch.None;
}
public void SetImage (Xwt.Drawing.Image image)
protected override void Initialize ()
{
if (image == null) {
Image.Source = null;
return;
}
ImageSource source = DataConverter.AsImageSource (Toolkit.GetBackend (image));
if (source == null)
source = DataConverter.AsImageSource (Toolkit.GetBackend (image.ToBitmap ()));
if (source == null)
throw new ArgumentException ("image is not of the expected type", "image");
Image.Source = source;
base.Initialize ();
Widget = new ImageBox (Context);
}
protected Image Image
public void SetImage (ImageDescription image)
{
get { return (Image) NativeWidget; }
Image.ImageSource = image;
}
protected ImageBox Image
{
get { return (ImageBox)NativeWidget; }
}
}
}

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

@ -98,20 +98,12 @@ namespace Xwt.WPFBackend
set { this.menuItem.Visibility = (value) ? Visibility.Visible : Visibility.Collapsed; }
}
public void SetImage (object imageBackend)
public void SetImage (ImageDescription imageBackend)
{
if (imageBackend == null)
if (imageBackend.IsNull)
this.menuItem.Icon = null;
else
{
var img = (SWMI.BitmapSource) imageBackend;
this.menuItem.Icon = new System.Windows.Controls.Image
{
Source = img,
Width = img.Width,
Height = img.Height
};
}
this.menuItem.Icon = new ImageBox (Context) { ImageSource = imageBackend };
}
public void SetSubmenu (IMenuBackend menu)

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

@ -40,5 +40,15 @@ namespace Xwt.WPFBackend
Matrix m = source.CompositionTarget.TransformToDevice;
return new Size (m.M11, m.M22);
}
public static double GetScaleFactor (this Visual self)
{
PresentationSource source = PresentationSource.FromVisual (self);
if (source == null)
return 1;
Matrix m = source.CompositionTarget.TransformToDevice;
return m.M11;
}
}
}

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

@ -173,7 +173,7 @@ namespace Xwt.WPFBackend
if (!(Widget is Control)) {
double size = WpfFontBackendHandler.GetPointsFromDeviceUnits (SystemFonts.MessageFontSize);
return new FontData (SystemFonts.MessageFontFamily, size, Drawing.FontSizeUnit.Points) {
return new FontData (SystemFonts.MessageFontFamily, size) {
Style = SystemFonts.MessageFontStyle,
Weight = SystemFonts.MessageFontWeight
};

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

@ -120,9 +120,9 @@ namespace Xwt.WPFBackend
}
}
public void SetIcon (object imageBackend)
public void SetIcon (ImageDescription imageBackend)
{
window.Icon = DataConverter.AsImageSource (imageBackend);
window.Icon = imageBackend.ToImageSource ();
}
string IWindowFrameBackend.Title {
@ -150,6 +150,13 @@ namespace Xwt.WPFBackend
}
}
object IWindowFrameBackend.Screen {
get {
var sb = Bounds;
return System.Windows.Forms.Screen.FromRectangle (new System.Drawing.Rectangle ((int)sb.X, (int)sb.Y, (int)sb.Width, (int)sb.Height));
}
}
public void Move (double x, double y)
{
var value = ToNonClientRect (new Rectangle (x, y, 1, 1));

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

@ -19,6 +19,7 @@
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DebugType>full</DebugType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
@ -27,6 +28,7 @@
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DebugType>none</DebugType>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />

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

@ -62,11 +62,9 @@ namespace Xwt.Backends
public abstract void DrawTextLayout (object backend, TextLayout layout, double x, double y);
public abstract bool CanDrawImage (object backend, object img);
public abstract void DrawImage (object backend, ImageDescription img, double x, double y);
public abstract void DrawImage (object backend, object img, double x, double y, double width, double height, double alpha);
public abstract void DrawImage (object backend, object img, Rectangle srcRect, Rectangle destRect, double width, double height, double alpha);
public abstract void DrawImage (object backend, ImageDescription img, Rectangle srcRect, Rectangle destRect);
public abstract void Rotate (object backend, double angle);

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

@ -61,9 +61,20 @@ namespace Xwt.Backends
/// Gets the name of the screen device.
/// </summary>
/// <returns>The screen device name.</returns>
/// <param name="backend">Backend.</param>
/// <param name="backend">A screen backend</param>
public abstract string GetScreenDeviceName (object backend);
/// <summary>
/// Gets the scale factor for the screen.
/// </summary>
/// <returns>The scale factor.</returns>
/// <param name="backend">A screen backend</param>
/// <remarks>The normal value is 1. In a retina display the value is 2.</remarks>
public virtual double GetScaleFactor (object backend)
{
return 1d;
}
/// <summary>
/// Raises the ScreensChanged event.
/// </summary>

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

@ -31,10 +31,10 @@ namespace Xwt.Backends
{
public abstract class FontBackendHandler: BackendHandler
{
public abstract object Create (string fontName, double size, FontSizeUnit sizeUnit, FontStyle style, FontWeight weight, FontStretch stretch);
public abstract object Create (string fontName, double size, FontStyle style, FontWeight weight, FontStretch stretch);
public abstract object Copy (object handle);
public abstract object SetSize (object handle, double size, FontSizeUnit unit);
public abstract object SetSize (object handle, double size);
public abstract object SetFamily (object handle, string family);
public abstract object SetStyle (object handle, FontStyle style);
public abstract object SetWeight (object handle, FontWeight weight);

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

@ -30,6 +30,8 @@ namespace Xwt.Backends
{
public interface IAlertDialogBackend: IDisposable
{
void Initialize (ApplicationContext context);
Command Run (WindowFrame transientFor, MessageDescription message);
bool ApplyToAll { get; }

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

@ -33,7 +33,7 @@ namespace Xwt.Backends
{
void SetButtonStyle (ButtonStyle style);
void SetButtonType (ButtonType type);
void SetContent (string label, Image image, ContentPosition position);
void SetContent (string label, ImageDescription image, ContentPosition position);
}
public interface IButtonEventSink: IWidgetEventSink

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

@ -33,9 +33,8 @@ namespace Xwt.Backends
/// <summary>
/// Sets the image view to use the supplied image backend.
/// </summary>
/// <param name="nativeImage">An image</param>
/// <exception cref="ArgumentNullException"><paramref name="nativeImage"/> is <c>null</c>.</exception>
void SetImage (Image nativeImage);
/// <param name="image">An image</param>
void SetImage (ImageDescription image);
}
}

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

@ -42,8 +42,8 @@ namespace Xwt.Backends
/// <summary>
/// Sets the image to display for the menu item.
/// </summary>
/// <param name="imageBackend">The image backend to set as the image for this menu item.</param>
void SetImage (object imageBackend);
/// <param name="image">The image backend to set as the image for this menu item.</param>
void SetImage (ImageDescription image);
/// <summary>
/// Gets or sets the label for the menu item.

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

@ -33,7 +33,7 @@ namespace Xwt.Backends
{
void SetMenu (object menuBackend);
void SetImage (object imageBackend);
void SetImage (ImageDescription img);
}
}

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

@ -60,7 +60,7 @@ namespace Xwt.Backends
void SetTransientFor (IWindowFrameBackend window);
bool Resizable { get; set; }
void SetIcon (object imageBackend);
void SetIcon (ImageDescription image);
/// <summary>
/// Presents a window to the user. This may mean raising the window in the stacking order,
@ -73,6 +73,12 @@ namespace Xwt.Backends
/// </summary>
/// <value><c>true</c> if the window is in full screen mode; otherwise, <c>false</c>.</value>
bool FullScreen { get; set; }
/// <summary>
/// Gets the screen on which most of the area of this window is placed
/// </summary>
/// <value>The screen.</value>
object Screen { get; }
}
public interface IWindowFrameEventSink

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

@ -28,6 +28,7 @@ using System;
using System.IO;
using System.Reflection;
using Xwt.Drawing;
using System.Collections.Generic;
namespace Xwt.Backends
{
@ -57,6 +58,26 @@ namespace Xwt.Backends
return LoadFromStream (s);
}
/// <summary>
/// Creates an image that is custom drawn
/// </summary>
/// <returns>The custom drawn.</returns>
/// <param name="drawCallback">The callback to be used to draw the image. The arguments are: the context backend, the bounds where to draw</param>
public virtual object CreateCustomDrawn (ImageDrawCallback drawCallback)
{
throw new NotSupportedException ();
}
/// <summary>
/// Creates an image with multiple representations in different sizes
/// </summary>
/// <returns>The image backend</returns>
/// <param name="images">Backends of the different image representations</param>
public virtual object CreateMultiSizeImage (IEnumerable<object> images)
{
throw new NotSupportedException ();
}
public abstract object LoadFromStream (Stream stream);
public abstract void SaveToStream (object backend, System.IO.Stream stream, ImageFileType fileType);
@ -76,7 +97,7 @@ namespace Xwt.Backends
/// <param name="handle">Image handle.</param>
/// <param name="width">Width.</param>
/// <param name="height">Height.</param>
public abstract object ConvertToBitmap (object handle, double width, double height);
public abstract object ConvertToBitmap (object handle, int pixelWidth, int pixelHeight, ImageFormat format);
/// <summary>
/// Returns True if the image has multiple representations of different sizes.
@ -92,19 +113,30 @@ namespace Xwt.Backends
/// <param name="handle">Image handle</param>
public abstract Size GetSize (object handle);
public abstract object ResizeBitmap (object handle, double width, double height);
public abstract object CopyBitmap (object handle);
public abstract void CopyBitmapArea (object srcHandle, int srcX, int srcY, int width, int height, object destHandle, int destX, int destY);
public abstract object CropBitmap (object handle, int srcX, int srcY, int width, int height);
public abstract object ChangeBitmapOpacity (object backend, double opacity);
public abstract void SetBitmapPixel (object handle, int x, int y, Color color);
public abstract Color GetBitmapPixel (object handle, int x, int y);
}
public delegate void ImageDrawCallback (object contextBackend, Rectangle bounds);
public struct ImageDescription
{
public static ImageDescription Null = new ImageDescription ();
public bool IsNull {
get { return Backend == null; }
}
public object Backend { get; set; }
public Size Size { get; set; }
public double Alpha { get; set; }
}
}

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

@ -29,8 +29,8 @@ namespace Xwt.Backends
{
public abstract class ImagePatternBackendHandler: BackendHandler
{
public abstract object Create (object img);
public abstract void Dispose (object img);
public abstract object Create (ImageDescription img);
public abstract void Dispose (object backend);
}
}

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

@ -53,6 +53,15 @@ namespace Xwt.Backends
InitializeApplication ();
}
public static T GetToolkitBackend<T> () where T : ToolkitEngineBackend
{
return (T)Toolkit.GetToolkitBackend (typeof (T));
}
public ApplicationContext ApplicationContext {
get { return toolkit.Context; }
}
/// <summary>
/// Gets a value indicating whether this toolkit is running as a guest of another toolkit
/// </summary>
@ -272,6 +281,11 @@ namespace Xwt.Backends
/// <remarks>This funciton is used to determine if a widget is a child of another non-XWT widget
/// </remarks>
public abstract bool HasNativeParent (Widget w);
public static ImageDescription GetImageDescription (Image img)
{
return img != null ? img.ImageDescription : ImageDescription.Null;
}
}
}

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

@ -77,11 +77,6 @@ namespace Xwt.Drawing
{
return new BitmapImage (ToolkitEngine.ImageBackendHandler.CropBitmap (Backend, srcX, srcY, width, height));
}
public new BitmapImage WithAlpha (double alpha)
{
return new BitmapImage (ToolkitEngine.ImageBackendHandler.ChangeBitmapOpacity (Backend, alpha));
}
}
}

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

@ -38,9 +38,13 @@ namespace Xwt.Drawing
double globalAlpha = 1;
Stack<double> alphaStack = new Stack<double> ();
internal Context (object backend, Toolkit toolkit): base (backend, toolkit, toolkit.ContextBackendHandler)
internal Context (object backend, Toolkit toolkit): this (backend, toolkit, toolkit.ContextBackendHandler)
{
handler = toolkit.ContextBackendHandler;
}
internal Context (object backend, Toolkit toolkit, ContextBackendHandler handler): base (backend, toolkit, handler)
{
this.handler = handler;
}
/// <summary>
@ -146,35 +150,9 @@ namespace Xwt.Drawing
if (!img.HasFixedSize)
throw new InvalidOperationException ("Image doesn't have a fixed size");
if (img.CanDrawInContext (img.Size.Width, img.Size.Height)) {
DrawInContext (img, x, y, img.Size.Width, img.Size.Height, alpha);
return;
}
var bk = GetImageBackend (img);
handler.DrawImage (Backend, bk, x, y, img.Size.Width, img.Size.Height, alpha);
}
void DrawInContext (Image img, double x, double y, double width, double height, double alpha)
{
try {
Save ();
NewPath ();
Rectangle (x, y, width, height);
Clip ();
GlobalAlpha *= alpha;
img.DrawInContext (this, x, y, width, height);
} finally {
Restore ();
}
}
object GetImageBackend (Image img)
{
var bk = img.SelectedBackend;
if (bk == null || !handler.CanDrawImage (Backend, bk))
return GetBackend (img.ToBitmap ());
else
return bk;
var idesc = img.ImageDescription;
idesc.Alpha *= alpha;
handler.DrawImage (Backend, idesc, x, y);
}
public void DrawImage (Image img, Rectangle rect, double alpha = 1)
@ -184,12 +162,10 @@ namespace Xwt.Drawing
public void DrawImage (Image img, double x, double y, double width, double height, double alpha = 1)
{
if (img.CanDrawInContext (width, height)) {
DrawInContext (img, x, y, width, height, alpha);
return;
}
var bk = GetImageBackend (img.WithSize (width, height));
handler.DrawImage (Backend, bk, x, y, width, height, alpha);
var idesc = img.ImageDescription;
idesc.Alpha *= alpha;
idesc.Size = new Size (width, height);
handler.DrawImage (Backend, idesc, x, y);
}
public void DrawImage (Image img, Rectangle srcRect, Rectangle destRect)
@ -202,30 +178,9 @@ namespace Xwt.Drawing
if (!img.HasFixedSize)
throw new InvalidOperationException ("Image doesn't have a fixed size");
if (img.CanDrawInContext (img.Size.Width, img.Size.Height)) {
try {
Save ();
GlobalAlpha *= alpha;
NewPath ();
Rectangle (destRect);
Clip ();
var scaleX = destRect.Width / srcRect.Width;
var scaleY = destRect.Height / srcRect.Height;
Translate (destRect.X - srcRect.X * scaleX, destRect.Y - srcRect.Y * scaleY);
Scale (scaleX, scaleY);
img.DrawInContext (this, 0, 0, img.Size.Width, img.Size.Height);
} finally {
Restore ();
}
return;
}
var bk = GetImageBackend (img);
handler.DrawImage (Backend, bk, srcRect, destRect, img.Size.Width, img.Size.Height, alpha);
var idesc = img.ImageDescription;
idesc.Alpha *= alpha;
handler.DrawImage (Backend, idesc, srcRect, destRect);
}
/// <summary>

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

@ -31,28 +31,14 @@ namespace Xwt.Drawing
{
public DrawingImage ()
{
Backend = Toolkit.CurrentEngine.ImageBackendHandler.CreateCustomDrawn (Draw);
Init ();
}
protected override BitmapImage GenerateBitmap (Size size, double alpha)
void Draw (object ctx, Rectangle bounds)
{
using (ImageBuilder ib = new ImageBuilder ((int)size.Width, (int)size.Height)) {
ib.Context.GlobalAlpha = alpha;
OnDraw (ib.Context, new Rectangle (0, 0, size.Width, size.Height));
return ib.ToImage ().ToBitmap ();
}
}
internal override bool CanDrawInContext (double width, double height)
{
return true;
}
internal override void DrawInContext (Context ctx, double x, double y, double width, double height)
{
var oldAlpha = ctx.GlobalAlpha;
ctx.GlobalAlpha *= requestedAlpha;
OnDraw (ctx, new Rectangle (x, y, width, height));
ctx.GlobalAlpha = oldAlpha;
var c = new Context (ctx, ToolkitEngine);
OnDraw (c, bounds);
}
protected virtual void OnDraw (Context ctx, Rectangle bounds)

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

@ -39,7 +39,6 @@ namespace Xwt.Drawing
public sealed class Font: XwtObject
{
FontBackendHandler handler;
FontSizeUnit unit;
internal Font (object backend): this (backend, null)
{
@ -73,13 +72,8 @@ namespace Xwt.Drawing
throw new ArgumentException ("Font family name or size not specified");
double size = 0;
FontSizeUnit unit = FontSizeUnit.Points;
var s = parts[parts.Length - 1];
if (s.EndsWith ("px")) {
s = s.Substring (0, s.Length - 2);
unit = FontSizeUnit.Pixels;
}
if (!double.TryParse (s, out size))
throw new ArgumentException ("Invalid font size: " + s);
@ -105,7 +99,7 @@ namespace Xwt.Drawing
string fname = string.Join (" ", parts, 0, i + 1);
return new Font (handler.Create (fname, size, unit, style, weight, stretch), toolkit);
return new Font (handler.Create (fname, size, style, weight, stretch), toolkit);
}
public Font WithFamily (string fontFamily)
@ -128,24 +122,14 @@ namespace Xwt.Drawing
}
}
public FontSizeUnit SizeUnit {
get { return unit; }
}
public Font WithPointSize (double size)
public Font WithSize (double size)
{
return new Font (handler.SetSize (Backend, size, FontSizeUnit.Points));
}
public Font WithPixelSize (double size)
{
return new Font (handler.SetSize (Backend, size, FontSizeUnit.Pixels));
return new Font (handler.SetSize (Backend, size));
}
public Font WithScaledSize (double scale)
{
return new Font (handler.SetSize (Backend, Size * scale, unit), ToolkitEngine);
return new Font (handler.SetSize (Backend, Size * scale), ToolkitEngine);
}
public FontStyle Style {
@ -191,18 +175,10 @@ namespace Xwt.Drawing
if (Stretch != FontStretch.Normal)
sb.Append (' ').Append (Stretch);
sb.Append (' ').Append (Size.ToString (CultureInfo.InvariantCulture));
if (unit == FontSizeUnit.Pixels)
sb.Append ("px");
return sb.ToString ();
}
}
public enum FontSizeUnit
{
Pixels,
Points
}
public enum FontStyle
{
Normal,

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

@ -29,6 +29,7 @@ using Xwt.Backends;
using System.Reflection;
using System.IO;
using System.Collections.Generic;
namespace Xwt.Drawing
{
@ -36,11 +37,11 @@ namespace Xwt.Drawing
{
Size requestedSize;
internal NativeImageRef NativeRef;
Image sourceImage;
BitmapImage cachedBitmap;
internal double requestedAlpha = 1;
static readonly object NoBackend = new object ();
internal Image ()
{
}
internal Image (object backend): base (backend)
{
@ -54,23 +55,11 @@ namespace Xwt.Drawing
public Image (Image image): base (image.Backend, image.ToolkitEngine)
{
if (image.NativeRef != null) {
NativeRef = image.NativeRef;
Init ();
}
else
sourceImage = image.sourceImage ?? image;
}
protected Image (Toolkit toolkit): base (NoBackend, toolkit)
{
}
protected Image (): base (NoBackend)
{
}
void Init ()
internal void Init ()
{
if (NativeRef == null) {
NativeRef = new NativeImageRef (Backend, ToolkitEngine);
@ -95,21 +84,58 @@ namespace Xwt.Drawing
NativeRef.ReleaseReference (disposing);
}
public static Image FromResource (Type type, string resource)
{
var toolkit = Toolkit.CurrentEngine;
var img = toolkit.ImageBackendHandler.LoadFromResource (type.Assembly, resource);
if (img == null)
throw new InvalidOperationException ("Resource not found: " + resource);
return new Image (img, toolkit);
internal ImageDescription ImageDescription {
get {
return new ImageDescription () {
Alpha = requestedAlpha,
Size = Size,
Backend = Backend
};
}
}
public static Image FromResource (Assembly asm, string resource)
public static Image FromResource (Type type, string resource)
{
if (type == null)
throw new ArgumentNullException ("type");
if (resource == null)
throw new ArgumentNullException ("resource");
return FromResource (type.Assembly, resource);
}
public static Image FromResource (Assembly assembly, string resource)
{
if (assembly == null)
throw new ArgumentNullException ("assembly");
if (resource == null)
throw new ArgumentNullException ("resource");
var toolkit = Toolkit.CurrentEngine;
var img = toolkit.ImageBackendHandler.LoadFromResource (asm, resource);
var name = Path.GetFileNameWithoutExtension (resource);
var img = toolkit.ImageBackendHandler.LoadFromResource (assembly, resource);
if (img == null)
throw new InvalidOperationException ("Resource not found: " + resource);
List<object> altImages = new List<object> ();
foreach (var r in assembly.GetManifestResourceNames ()) {
int i = r.LastIndexOf ('@');
if (i != -1) {
string rname = r.Substring (0, i);
if (rname == resource || rname == name) {
var rim = toolkit.ImageBackendHandler.LoadFromResource (assembly, r);
if (rim != null)
altImages.Add (rim);
}
}
}
if (altImages.Count > 0) {
altImages.Insert (0, img);
img = toolkit.ImageBackendHandler.CreateMultiSizeImage (altImages);
}
return new Image (img, toolkit);
}
@ -125,11 +151,6 @@ namespace Xwt.Drawing
return new Image (toolkit.ImageBackendHandler.LoadFromStream (stream), toolkit);
}
public static Image FromMultipleSizes (params Image[] images)
{
return new ImageSet (images);
}
public void Save (string file, ImageFileType fileType)
{
using (var f = File.OpenWrite (file))
@ -141,12 +162,6 @@ namespace Xwt.Drawing
ToolkitEngine.ImageBackendHandler.SaveToStream (ToBitmap ().Backend, stream, fileType);
}
internal virtual object SelectedBackend {
get {
return Backend != NoBackend ? Backend : null;
}
}
public bool HasFixedSize {
get { return !Size.IsZero; }
}
@ -155,11 +170,14 @@ namespace Xwt.Drawing
get {
if (!requestedSize.IsZero)
return requestedSize;
if (Backend != NoBackend && !ToolkitEngine.ImageBackendHandler.HasMultipleSizes (Backend))
if (!ToolkitEngine.ImageBackendHandler.HasMultipleSizes (Backend))
return ToolkitEngine.ImageBackendHandler.GetSize (Backend);
else
return Size.Zero;
}
internal set {
requestedSize = value;
}
}
public Image WithAlpha (double alpha)
@ -211,8 +229,6 @@ namespace Xwt.Drawing
get {
if (!requestedSize.IsZero)
return requestedSize;
if (Backend != NoBackend)
return ToolkitEngine.ImageBackendHandler.GetSize (Backend);
else
return GetDefaultSize ();
}
@ -270,74 +286,39 @@ namespace Xwt.Drawing
};
}
public BitmapImage ToBitmap ()
public BitmapImage ToBitmap (ImageFormat format = ImageFormat.ARGB32)
{
var size = GetFixedSize ();
var bmp = GetCachedBitmap (size, requestedAlpha);
if (bmp != null)
return bmp;
if (sourceImage != null)
bmp = sourceImage.ToBitmap (size, requestedAlpha);
else
bmp = ToBitmap (size, requestedAlpha);
return cachedBitmap = bmp;
var s = GetFixedSize ();
return ToBitmap ((int)s.Width, (int)s.Height);
}
BitmapImage ToBitmap (Size size, double alpha)
public BitmapImage ToBitmap (Widget renderTarget, ImageFormat format = ImageFormat.ARGB32)
{
// Don't cache the bitmap here since this method may be called by other image instances
return GetCachedBitmap (size, alpha) ?? GenerateBitmap (size, alpha);
if (renderTarget.ParentWindow == null)
throw new InvalidOperationException ("renderTarget is not bounds to a window");
return ToBitmap (renderTarget.ParentWindow, format);
}
BitmapImage GetCachedBitmap (Size size, double alpha)
public BitmapImage ToBitmap (WindowFrame renderTarget, ImageFormat format = ImageFormat.ARGB32)
{
return cachedBitmap != null && size == cachedBitmap.Size && this.requestedAlpha == alpha ? cachedBitmap : null;
return ToBitmap (renderTarget.Screen, format);
}
protected virtual BitmapImage GenerateBitmap (Size size, double alpha)
public BitmapImage ToBitmap (Screen renderTarget, ImageFormat format = ImageFormat.ARGB32)
{
if (Backend != NoBackend) {
object bmp = Backend;
if (ToolkitEngine.ImageBackendHandler.IsBitmap (bmp)) {
if (size == ToolkitEngine.ImageBackendHandler.GetSize (bmp)) {
if (alpha == 1)
// The backend can be shared
return new BitmapImage (this);
var s = GetFixedSize ();
return ToBitmap ((int)(s.Width * renderTarget.ScaleFactor), (int)(s.Height * renderTarget.ScaleFactor), format);
}
else
// Create a new backend with the new size
bmp = ToolkitEngine.ImageBackendHandler.ResizeBitmap (Backend, size.Width, size.Height);
}
else
bmp = ToolkitEngine.ImageBackendHandler.ConvertToBitmap (Backend, size.Width, size.Height);
if (alpha != 1) {
var oldBmp = bmp;
bmp = ToolkitEngine.ImageBackendHandler.ChangeBitmapOpacity (bmp, alpha);
ToolkitEngine.ImageBackendHandler.Dispose (oldBmp);
}
public BitmapImage ToBitmap (int pixelWidth, int pixelHeight, ImageFormat format = ImageFormat.ARGB32)
{
var bmp = ToolkitEngine.ImageBackendHandler.ConvertToBitmap (Backend, pixelWidth, pixelHeight, format);
return new BitmapImage (bmp);
}
throw new NotSupportedException ();
}
protected virtual Size GetDefaultSize ()
{
return Size.Zero;
}
internal virtual bool CanDrawInContext (double width, double height)
{
return sourceImage != null ? sourceImage.CanDrawInContext (width, height) : false;
}
internal virtual void DrawInContext (Context ctx, double x, double y, double width, double height)
{
if (sourceImage != null)
sourceImage.DrawInContext (ctx, x, y, width, height);
return ToolkitEngine.ImageBackendHandler.GetSize (Backend);
}
}

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

@ -26,6 +26,7 @@
using System;
using Xwt;
using Xwt.Backends;
using System.Collections.Generic;
namespace Xwt.Drawing
@ -33,36 +34,31 @@ namespace Xwt.Drawing
public sealed class ImageBuilder: XwtObject, IDisposable
{
Context ctx;
ImageBuilderBackendHandler handler;
object backend;
int width;
int height;
VectorContextBackend backend;
double width;
double height;
public ImageBuilder (int width, int height): this (width, height, ImageFormat.ARGB32)
{
}
static VectorImageRecorderContextHandler vectorImageRecorderContextHandler = new VectorImageRecorderContextHandler ();
public ImageBuilder (int width, int height, ImageFormat format)
public ImageBuilder (double width, double height)
{
handler = ToolkitEngine.ImageBuilderBackendHandler;
backend = new VectorContextBackend ();
ctx = new Context (backend, ToolkitEngine, vectorImageRecorderContextHandler);
this.width = width;
this.height = height;
backend = handler.CreateImageBuilder (width, height, format);
ctx = new Context (handler.CreateContext (backend), ToolkitEngine);
}
public int Width {
public double Width {
get { return width; }
}
public int Height {
public double Height {
get { return height; }
}
public void Dispose ()
{
ctx.Dispose ();
handler.Dispose (backend);
}
public Context Context {
@ -71,10 +67,34 @@ namespace Xwt.Drawing
}
}
public Image ToImage ()
public Image ToVectorImage ()
{
return new Image (handler.CreateImage (backend), ToolkitEngine);
return new VectorImage (new Size (width, height), backend.ToVectorImageData ());
}
public BitmapImage ToBitmap (ImageFormat format = ImageFormat.ARGB32)
{
return ToVectorImage ().ToBitmap (format);
}
public BitmapImage ToBitmap (Widget renderTarget, ImageFormat format = ImageFormat.ARGB32)
{
return ToVectorImage ().ToBitmap (renderTarget, format);
}
public BitmapImage ToBitmap (Window renderTarget, ImageFormat format = ImageFormat.ARGB32)
{
return ToVectorImage ().ToBitmap (renderTarget, format);
}
public BitmapImage ToBitmap (Screen renderTarget, ImageFormat format = ImageFormat.ARGB32)
{
return ToVectorImage ().ToBitmap (renderTarget, format);
}
public BitmapImage ToBitmap (int pixelWidth, int pixelHeight, ImageFormat format = ImageFormat.ARGB32)
{
return ToVectorImage ().ToBitmap (pixelWidth, pixelHeight, format);
}
}
}

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

@ -31,9 +31,9 @@ namespace Xwt.Drawing
{
public sealed class ImagePattern: Pattern
{
public ImagePattern (Image img)
public ImagePattern (Image image)
{
Backend = ToolkitEngine.ImagePatternBackendHandler.Create (GetBackend (img));
Backend = ToolkitEngine.ImagePatternBackendHandler.Create (image != null ? image.ImageDescription : ImageDescription.Null);
}
public override void Dispose ()

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

@ -1,81 +0,0 @@
//
// ImageSet.cs
//
// Author:
// Lluis Sanchez <lluis@xamarin.com>
//
// Copyright (c) 2013 Xamarin Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Linq;
namespace Xwt.Drawing
{
class ImageSet: Image
{
Image[] images;
public ImageSet (Image[] images)
{
if (images.Count (i => !i.HasFixedSize) > 1)
throw new InvalidOperationException ("There is more than one image with unbound size");
this.images = images.OrderBy (i => i.HasFixedSize ? i.Size.Width + i.Size.Height : int.MaxValue).ToArray ();
}
internal override object SelectedBackend {
get {
var s = GetFixedSize ();
return GetBackend (SelectImage (s.Width, s.Height));
}
}
Image SelectImage (double width, double height)
{
foreach (var img in images) {
if (!img.HasFixedSize || (width + height <= img.Size.Width + img.Size.Height))
return img;
}
return images [images.Length - 1];
}
internal override bool CanDrawInContext (double width, double height)
{
var img = SelectImage (width, height);
return img.CanDrawInContext (width, height);
}
internal override void DrawInContext (Context ctx, double x, double y, double width, double height)
{
var img = SelectImage (width, height);
img.DrawInContext (ctx, x, y, width, height);
}
protected override BitmapImage GenerateBitmap (Size size, double alpha)
{
var img = SelectImage (size.Width, size.Height);
if (img.Size.Width != size.Width || img.Size.Height != size.Height)
img = img.WithSize (size);
if (alpha != 1)
img = img.WithAlpha (alpha);
return img.ToBitmap ();
}
}
}

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

@ -0,0 +1,544 @@
//
// VectorImage.cs
//
// Author:
// Lluis Sanchez <lluis@xamarin.com>
//
// Copyright (c) 2013 Xamarin Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using Xwt.Backends;
using System.Collections.Generic;
namespace Xwt.Drawing
{
class VectorImage: DrawingImage
{
VectorImageData data;
public VectorImage (Size s, VectorImageData data)
{
this.data = data;
Size = s;
}
protected override void OnDraw (Context ctx, Rectangle bounds)
{
ctx.Save ();
ctx.Translate (bounds.Location);
ctx.Scale (bounds.Width / Size.Width, bounds.Height / Size.Height);
VectorImageRecorderContextHandler.Draw (ToolkitEngine.ContextBackendHandler, Toolkit.GetBackend (ctx), data);
ctx.Restore ();
}
}
class VectorImageData
{
public DrawingCommand[] Commands;
public double[] Doubles;
public Color[] Colors;
public int[] Ints;
public Rectangle[] Rectangles;
public object[] Objects;
public ImageDescription[] Images;
}
enum DrawingCommand
{
Save,
Restore,
SetGlobalAlpha,
SetColor,
Clip,
ClipPreserve,
Arc,
ArcNegative,
ClosePath,
CurveTo,
LineTo,
Fill,
FillPreserve,
NewPath,
Stroke,
StrokePreserve,
SetLineWidth,
SetLineDash,
SetPattern,
SetFont,
DrawTextLayout,
CanDrawImage,
DrawImage,
DrawImage2,
Rotate,
Scale,
Translate,
MoveTo,
Rectangle,
RelCurveTo,
RelLineTo,
RelMoveTo,
AppendPath,
End
}
class VectorContextBackend
{
public List<DrawingCommand> Commands = new List<DrawingCommand> ();
public List<double> Doubles = new List<double> ();
public List<Color> Colors = new List<Color> ();
public List<int> Ints = new List<int> ();
public List<Rectangle> Rectangles = new List<Rectangle> ();
public List<object> Objects = new List<object> ();
public List<ImageDescription> Images = new List<ImageDescription> ();
public VectorContextBackend Clone ()
{
var c = new VectorContextBackend ();
c.Commands.AddRange (Commands);
c.Doubles.AddRange (Doubles);
c.Colors.AddRange (Colors);
c.Images.AddRange (Images);
c.Ints.AddRange (Ints);
c.Rectangles.AddRange (Rectangles);
c.Objects.AddRange (Objects);
return c;
}
public VectorImageData ToVectorImageData ()
{
return new VectorImageData () {
Commands = Commands.ToArray (),
Doubles = Doubles.ToArray (),
Colors = Colors.ToArray (),
Images = Images.ToArray (),
Ints = Ints.ToArray (),
Rectangles = Rectangles.ToArray (),
Objects = Objects.ToArray ()
};
}
}
class VectorImageRecorderContextHandler: ContextBackendHandler
{
#region implemented abstract members of DrawingPathBackendHandler
public override void Arc (object backend, double xc, double yc, double radius, double angle1, double angle2)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.Arc);
ctx.Doubles.Add (xc);
ctx.Doubles.Add (yc);
ctx.Doubles.Add (radius);
ctx.Doubles.Add (angle1);
ctx.Doubles.Add (angle2);
}
public override void ArcNegative (object backend, double xc, double yc, double radius, double angle1, double angle2)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.ArcNegative);
ctx.Doubles.Add (xc);
ctx.Doubles.Add (yc);
ctx.Doubles.Add (radius);
ctx.Doubles.Add (angle1);
ctx.Doubles.Add (angle2);
}
public override void ClosePath (object backend)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.ClosePath);
}
public override void CurveTo (object backend, double x1, double y1, double x2, double y2, double x3, double y3)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.CurveTo);
ctx.Doubles.Add (x1);
ctx.Doubles.Add (y1);
ctx.Doubles.Add (x2);
ctx.Doubles.Add (y2);
ctx.Doubles.Add (x3);
ctx.Doubles.Add (y3);
}
public override void LineTo (object backend, double x, double y)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.LineTo);
ctx.Doubles.Add (x);
ctx.Doubles.Add (y);
}
public override void MoveTo (object backend, double x, double y)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.MoveTo);
ctx.Doubles.Add (x);
ctx.Doubles.Add (y);
}
public override void Rectangle (object backend, double x, double y, double width, double height)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.Rectangle);
ctx.Doubles.Add (x);
ctx.Doubles.Add (y);
ctx.Doubles.Add (width);
ctx.Doubles.Add (height);
}
public override void RelCurveTo (object backend, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.RelCurveTo);
ctx.Doubles.Add (dx1);
ctx.Doubles.Add (dy1);
ctx.Doubles.Add (dx2);
ctx.Doubles.Add (dy2);
ctx.Doubles.Add (dx3);
ctx.Doubles.Add (dy3);
}
public override void RelLineTo (object backend, double dx, double dy)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.RelLineTo);
ctx.Doubles.Add (dx);
ctx.Doubles.Add (dy);
}
public override void RelMoveTo (object backend, double dx, double dy)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.RelMoveTo);
ctx.Doubles.Add (dx);
ctx.Doubles.Add (dy);
}
public override object CreatePath ()
{
return new VectorContextBackend ();
}
public override object CopyPath (object backend)
{
var ctx = (VectorContextBackend)backend;
return ctx.Clone ();
}
public override void AppendPath (object backend, object otherBackend)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.AppendPath);
ctx.Objects.Add (((VectorContextBackend)otherBackend).ToVectorImageData ());
}
#endregion
#region implemented abstract members of ContextBackendHandler
public override void Save (object backend)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.Save);
}
public override void Restore (object backend)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.Restore);
}
public override void Clip (object backend)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.Clip);
}
public override void ClipPreserve (object backend)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.ClipPreserve);
}
public override void Fill (object backend)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.Fill);
}
public override void FillPreserve (object backend)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.FillPreserve);
}
public override void NewPath (object backend)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.NewPath);
}
public override void Stroke (object backend)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.Stroke);
}
public override void StrokePreserve (object backend)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.StrokePreserve);
}
public override void SetColor (object backend, Color color)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.SetColor);
ctx.Colors.Add (color);
}
public override void SetLineWidth (object backend, double width)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.SetLineWidth);
ctx.Doubles.Add (width);
}
public override void SetLineDash (object backend, double offset, params double[] pattern)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.SetLineDash);
ctx.Doubles.Add (offset);
ctx.Ints.Add (pattern.Length);
for (int n=0; n<pattern.Length; n++)
ctx.Doubles.Add (pattern [n]);
}
public override void SetPattern (object backend, object p)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.SetPattern);
ctx.Objects.Add (p);
}
public override void SetFont (object backend, Font font)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.SetFont);
ctx.Objects.Add (font);
}
public override void DrawTextLayout (object backend, TextLayout layout, double x, double y)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.DrawTextLayout);
ctx.Objects.Add (layout);
}
public override void DrawImage (object backend, ImageDescription img, double x, double y)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.DrawImage);
ctx.Images.Add (img);
ctx.Doubles.Add (x);
ctx.Doubles.Add (y);
}
public override void DrawImage (object backend, ImageDescription img, Xwt.Rectangle srcRect, Xwt.Rectangle destRect)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.DrawImage2);
ctx.Images.Add (img);
ctx.Rectangles.Add (srcRect);
ctx.Rectangles.Add (destRect);
}
public override void Rotate (object backend, double angle)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.Rotate);
ctx.Doubles.Add (angle);
}
public override void Scale (object backend, double scaleX, double scaleY)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.Scale);
ctx.Doubles.Add (scaleX);
ctx.Doubles.Add (scaleY);
}
public override void Translate (object backend, double tx, double ty)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.Translate);
ctx.Doubles.Add (tx);
ctx.Doubles.Add (ty);
}
public override Matrix GetCTM (object backend)
{
throw new NotSupportedException ();
}
public override bool IsPointInStroke (object backend, double x, double y)
{
return false;
}
public override void SetGlobalAlpha (object backend, double globalAlpha)
{
var ctx = (VectorContextBackend)backend;
ctx.Commands.Add (DrawingCommand.SetGlobalAlpha);
ctx.Doubles.Add (globalAlpha);
}
public override bool IsPointInFill (object backend, double x, double y)
{
throw new NotSupportedException ();
}
public override void Dispose (object backend)
{
}
#endregion
internal static void Draw (ContextBackendHandler handler, object ctx, VectorImageData cm)
{
int di = 0;
int ci = 0;
int ii = 0;
int ri = 0;
int oi = 0;
int imi = 0;
for (int n=0; n<cm.Commands.Length; n++)
{
switch (cm.Commands [n]) {
case DrawingCommand.AppendPath:
var p = (VectorImageData)cm.Objects [oi++];
Draw (handler, ctx, p);
break;
case DrawingCommand.Arc:
handler.Arc (ctx, cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++]);
break;
case DrawingCommand.ArcNegative:
handler.ArcNegative (ctx, cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++]);
break;
case DrawingCommand.Clip:
handler.Clip (ctx);
break;
case DrawingCommand.ClipPreserve:
handler.ClipPreserve (ctx);
break;
case DrawingCommand.ClosePath:
handler.ClosePath (ctx);
break;
case DrawingCommand.CurveTo:
handler.CurveTo (ctx, cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++]);
break;
case DrawingCommand.DrawImage2:
handler.DrawImage (ctx, cm.Images [imi++], cm.Rectangles [ri++], cm.Rectangles [ri++]);
break;
case DrawingCommand.DrawImage:
handler.DrawImage (ctx, cm.Images [imi++], cm.Doubles [di++], cm.Doubles [di++]);
break;
case DrawingCommand.DrawTextLayout:
handler.DrawTextLayout (ctx, (TextLayout)cm.Objects [oi++], cm.Doubles [di++], cm.Doubles [di++]);
break;
case DrawingCommand.Fill:
handler.Fill (ctx);
break;
case DrawingCommand.FillPreserve:
handler.FillPreserve (ctx);
break;
case DrawingCommand.LineTo:
handler.LineTo (ctx, cm.Doubles [di++], cm.Doubles [di++]);
break;
case DrawingCommand.MoveTo:
handler.MoveTo (ctx, cm.Doubles [di++], cm.Doubles [di++]);
break;
case DrawingCommand.NewPath:
handler.NewPath (ctx);
break;
case DrawingCommand.Rectangle:
handler.Rectangle (ctx, cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++]);
break;
case DrawingCommand.RelCurveTo:
handler.RelCurveTo (ctx, cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++], cm.Doubles [di++]);
break;
case DrawingCommand.RelLineTo:
handler.RelLineTo (ctx, cm.Doubles [di++], cm.Doubles [di++]);
break;
case DrawingCommand.RelMoveTo:
handler.RelMoveTo (ctx, cm.Doubles [di++], cm.Doubles [di++]);
break;
case DrawingCommand.Restore:
handler.Restore (ctx);
break;
case DrawingCommand.Rotate:
handler.Rotate (ctx, cm.Doubles [di++]);
break;
case DrawingCommand.Save:
handler.Save (ctx);
break;
case DrawingCommand.Scale:
handler.Scale (ctx, cm.Doubles [di++], cm.Doubles [di++]);
break;
case DrawingCommand.SetColor:
handler.SetColor (ctx, cm.Colors [ci++]);
break;
case DrawingCommand.SetFont:
handler.SetFont (ctx, (Font)cm.Objects [oi++]);
break;
case DrawingCommand.SetGlobalAlpha:
handler.SetGlobalAlpha (ctx, cm.Doubles [di++]);
break;
case DrawingCommand.SetLineDash:
var off = cm.Doubles [di++];
var ds = new double [cm.Ints [ii++]];
for (int i = 0; i < ds.Length; i++)
ds [i] = cm.Doubles [di++];
handler.SetLineDash (ctx, off, ds);
break;
case DrawingCommand.SetLineWidth:
handler.SetLineWidth (ctx, cm.Doubles [di++]);
break;
case DrawingCommand.SetPattern:
handler.SetPattern (ctx, cm.Objects [oi++]);
break;
case DrawingCommand.Stroke:
handler.Stroke (ctx);
break;
case DrawingCommand.StrokePreserve:
handler.StrokePreserve (ctx);
break;
case DrawingCommand.Translate:
handler.Translate (ctx, cm.Doubles [di++], cm.Doubles [di++]);
break;
}
}
}
}
}

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

@ -382,11 +382,11 @@
<Compile Include="Xwt.Backends\StockIconId.cs" />
<Compile Include="Xwt.Drawing\DrawingImage.cs" />
<Compile Include="Xwt.Drawing\BitmapImage.cs" />
<Compile Include="Xwt.Drawing\ImageSet.cs" />
<Compile Include="Xwt.Formats\PlainTextFormat.cs" />
<Compile Include="Xwt.Drawing\ImageFileType.cs" />
<Compile Include="Xwt\Slider.cs" />
<Compile Include="Xwt.Backends\ISliderBackend.cs" />
<Compile Include="Xwt.Drawing\VectorImage.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup />

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

@ -94,7 +94,7 @@ namespace Xwt
get { return label ?? ""; }
set {
label = value;
Backend.SetContent (label, image, imagePosition);
Backend.SetContent (label, image != null ? image.ImageDescription : ImageDescription.Null, imagePosition);
OnPreferredSizeChanged ();
}
}
@ -104,7 +104,7 @@ namespace Xwt
get { return image; }
set {
image = value;
Backend.SetContent (label, value, imagePosition);
Backend.SetContent (label, image != null ? image.ImageDescription : ImageDescription.Null, imagePosition);
OnPreferredSizeChanged ();
}
}
@ -114,7 +114,7 @@ namespace Xwt
get { return imagePosition; }
set {
imagePosition = value;
Backend.SetContent (label, image, imagePosition);
Backend.SetContent (label, image != null ? image.ImageDescription : ImageDescription.Null, imagePosition);
OnPreferredSizeChanged ();
}
}

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

@ -360,7 +360,7 @@ namespace Xwt
ib.Context.Fill ();
}
}
colorBox = ib.ToImage ();
colorBox = ib.ToBitmap (this);
}
}
ctx.DrawImage (colorBox, padding, padding);

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

@ -154,7 +154,7 @@ namespace Xwt
return screens.FirstOrDefault (s => s.Bounds.Contains (x, y));
}
static Screen GetScreen (object sb)
internal static Screen GetScreen (object sb)
{
foreach (var s in Screens) {
var backend = Toolkit.GetBackend (s);

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

@ -53,7 +53,7 @@ namespace Xwt
get { return image; }
set {
image = value;
Backend.SetImage (value);
Backend.SetImage (image != null ? image.ImageDescription : ImageDescription.Null);
OnPreferredSizeChanged ();
}
}

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

@ -103,7 +103,7 @@ namespace Xwt
public Image Image {
get { return image; }
set { image = value; Backend.SetImage (XwtObject.GetBackend (value)); }
set { image = value; Backend.SetImage (image != null ? image.ImageDescription : ImageDescription.Null); }
}
public void Show ()

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

@ -49,7 +49,7 @@ namespace Xwt
}
public static void ShowError (WindowFrame parent, string primaryText, string secondaryText)
{
GenericAlert (parent, StockIconId.Error, primaryText, secondaryText, Command.Ok);
GenericAlert (parent, StockIcons.Error, primaryText, secondaryText, Command.Ok);
}
#endregion
@ -68,7 +68,7 @@ namespace Xwt
}
public static void ShowWarning (WindowFrame parent, string primaryText, string secondaryText)
{
GenericAlert (parent, StockIconId.Warning, primaryText, secondaryText, Command.Ok);
GenericAlert (parent, StockIcons.Warning, primaryText, secondaryText, Command.Ok);
}
#endregion
@ -88,7 +88,7 @@ namespace Xwt
}
public static void ShowMessage (WindowFrame parent, string primaryText, string secondaryText)
{
GenericAlert (parent, StockIconId.Information, primaryText, secondaryText, Command.Ok);
GenericAlert (parent, StockIcons.Information, primaryText, secondaryText, Command.Ok);
}
#endregion
@ -100,7 +100,7 @@ namespace Xwt
public static bool Confirm (string primaryText, string secondaryText, Command button)
{
return GenericAlert (RootWindow, StockIconId.Question, primaryText, secondaryText, Command.Cancel, button) == button;
return GenericAlert (RootWindow, StockIcons.Question, primaryText, secondaryText, Command.Cancel, button) == button;
}
public static bool Confirm (string primaryText, Command button, bool confirmIsDefault)
{
@ -109,7 +109,7 @@ namespace Xwt
public static bool Confirm (string primaryText, string secondaryText, Command button, bool confirmIsDefault)
{
return GenericAlert (RootWindow, StockIconId.Question, primaryText, secondaryText, confirmIsDefault ? 0 : 1, Command.Cancel, button) == button;
return GenericAlert (RootWindow, StockIcons.Question, primaryText, secondaryText, confirmIsDefault ? 0 : 1, Command.Cancel, button) == button;
}
public static bool Confirm (ConfirmationMessage message)
@ -126,7 +126,7 @@ namespace Xwt
public static Command AskQuestion (string primaryText, string secondaryText, params Command[] buttons)
{
return GenericAlert (RootWindow, StockIconId.Question, primaryText, secondaryText, buttons);
return GenericAlert (RootWindow, StockIcons.Question, primaryText, secondaryText, buttons);
}
public static Command AskQuestion (string primaryText, int defaultButton, params Command[] buttons)
{
@ -135,7 +135,7 @@ namespace Xwt
public static Command AskQuestion (string primaryText, string secondaryText, int defaultButton, params Command[] buttons)
{
return GenericAlert (RootWindow, StockIconId.Question, primaryText, secondaryText, defaultButton, buttons);
return GenericAlert (RootWindow, StockIcons.Question, primaryText, secondaryText, defaultButton, buttons);
}
public static Command AskQuestion (QuestionMessage message)
@ -144,12 +144,12 @@ namespace Xwt
}
#endregion
static Command GenericAlert (WindowFrame parent, string icon, string primaryText, string secondaryText, params Command[] buttons)
static Command GenericAlert (WindowFrame parent, Xwt.Drawing.Image icon, string primaryText, string secondaryText, params Command[] buttons)
{
return GenericAlert (parent, icon, primaryText, secondaryText, buttons.Length - 1, buttons);
}
static Command GenericAlert (WindowFrame parent, string icon, string primaryText, string secondaryText, int defaultButton, params Command[] buttons)
static Command GenericAlert (WindowFrame parent, Xwt.Drawing.Image icon, string primaryText, string secondaryText, int defaultButton, params Command[] buttons)
{
GenericMessage message = new GenericMessage () {
Icon = icon,
@ -169,6 +169,7 @@ namespace Xwt
return message.ApplyToAllButton;
IAlertDialogBackend backend = Toolkit.CurrentEngine.Backend.CreateBackend<IAlertDialogBackend> ();
backend.Initialize (Toolkit.CurrentEngine.Context);
using (backend) {
var res = backend.Run (parent ?? RootWindow, message);
@ -195,7 +196,7 @@ namespace Xwt
internal Command ApplyToAllButton { get; set; }
public string Icon { get; set; }
public Xwt.Drawing.Image Icon { get; set; }
public string Text { get; set; }
public string SecondaryText { get; set; }
@ -266,7 +267,7 @@ namespace Xwt
{
public QuestionMessage ()
{
Icon = StockIconId.Question;
Icon = StockIcons.Question;
}
public QuestionMessage (string text): this ()
@ -290,7 +291,7 @@ namespace Xwt
public ConfirmationMessage ()
{
Icon = StockIconId.Question;
Icon = StockIcons.Question;
Buttons.Add (Command.Cancel);
}

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

@ -79,6 +79,16 @@ namespace Xwt
return ToolkitEngine.DesktopBackend.IsPrimaryScreen (Backend);
}
}
/// <summary>
/// Gets the screen scale factor.
/// </summary>
/// <value>This is the scale of user space pixels in relation to phisical pixels. The normal value is 1. In a retina display the value is 2.</value>
public double ScaleFactor {
get {
return ToolkitEngine.DesktopBackend.GetScaleFactor (Backend);
}
}
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше