コード例 #1
0
        public static UIImage FromResource(Assembly assembly, string name)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }
            if (assembly == null)
            {
                assembly = Assembly.GetCallingAssembly();
            }
            var stream = assembly.GetManifestResourceStream(name);

            if (stream == null)
            {
                throw new ArgumentException(String.Format("No resource named `{0}' found", name));
            }

            byte [] buffer = new byte [stream.Length];
            stream.Read(buffer, 0, buffer.Length);
            unsafe
            {
                fixed(byte *p = &buffer[0])
                {
                    var data = NSData.FromBytes((IntPtr)p, (uint)stream.Length);

                    return(LoadFromData(data));
                }
            }
        }
コード例 #2
0
        public static SCNGeometrySource Create(List <SCNVector4> colors)
        {
            SCNGeometrySource result = null;

            unsafe
            {
                var bytes       = new List <byte>();
                var colorsArray = colors.ToArray();

                for (int i = 0; i < colors.Count; i++)
                {
                    fixed(SCNVector4 *point = &colorsArray[i])
                    {
                        var intPtr = new IntPtr(point);
                        var data   = NSData.FromBytes(intPtr, (nuint)SCNVector4.SizeInBytes);

                        bytes.AddRange(data.ToList());
                    }
                }

                var colorData = NSData.FromArray(bytes.ToArray());
                result = SCNGeometrySource.FromData(colorData,
                                                    SCNGeometrySourceSemantics.Color,
                                                    colors.Count,
                                                    true,
                                                    4,
                                                    sizeof(float),
                                                    0,
                                                    SCNVector4.SizeInBytes);
            }

            return(result);
        }
コード例 #3
0
            public override void DiscoveredCharacteristic(CBPeripheral peripheral,
                                                          CBService service, NSError error)
            {
                if (monitor.disposed)
                {
                    return;
                }

                foreach (var characteristic in service.Characteristics)
                {
                    if (characteristic.UUID == HeartRateMeasurementCharacteristicUUID)
                    {
                        service.Peripheral.SetNotifyValue(true, characteristic);
                    }
                    else if (characteristic.UUID == BodySensorLocationCharacteristicUUID)
                    {
                        service.Peripheral.ReadValue(characteristic);
                    }
                    else if (characteristic.UUID == HeartRateControlPointCharacteristicUUID)
                    {
                        service.Peripheral.WriteValue(NSData.FromBytes((IntPtr)1, 1),
                                                      characteristic, CBCharacteristicWriteType.WithResponse);
                    }
                }
            }
コード例 #4
0
ファイル: KimonoSketch.cs プロジェクト: yjpark/KimonoDesigner
        /// <summary>
        /// Converts the sketch to a bitmap image.
        /// </summary>
        /// <returns>The `UIImage` representation of the sketch.</returns>
        public UIImage ToImage()
        {
            // Convert the image and return
            var skPngdata = Draw();
            var data      = NSData.FromBytes(skPngdata.Data, (nuint)skPngdata.Size);

            return(new UIImage(data));
        }
コード例 #5
0
        public NSData AsData()
        {
            int size;

            var p = ToBlock (out size);
            var result = NSData.FromBytes (p, (uint) size);
            Marshal.FreeHGlobal (p);
            return result;
        }
コード例 #6
0
        /// <summary>
        /// Convert the Image sketch to a bitmap image.
        /// </summary>
        /// <returns>The sketch as a platform specific bitmap image.</returns>
        public NSImage GenerateImage(Point pt)
        {
            // Get image data from sketch
            var skPngdata = GenerateImageData(pt);

            // Convert to image and return
            var data = NSData.FromBytes(skPngdata.Data, (nuint)skPngdata.Size);

            return(new NSImage(data));
        }
コード例 #7
0
        public void DisplayDrawing()
        {
            // Get image data from sketch
            var skPngdata = Draw(640, 480);

            // Convert to image and display
            var data = NSData.FromBytes(skPngdata.Data, (nuint)skPngdata.Size);

            ImageView.Image = new NSImage(data);
        }
コード例 #8
0
        /// <summary>
        /// Refreshs the view by redrawing the gradient design bar.
        /// </summary>
        public void RefreshView()
        {
            // Get image data from sketch
            var skPngdata = Gradient.DrawPreview();

            // Convert to image and display
            var data = NSData.FromBytes(skPngdata.Data, (nuint)skPngdata.Size);

            Image = new NSImage(data);
        }
コード例 #9
0
    public UIImage SketchToImage()
    {
        // Get image data from sketch
        var skPngdata = SketchToData();

        // Convert to image and return
        var data = NSData.FromBytes(skPngdata.Data, (nuint)skPngdata.Size);

        return(new UIImage(data));
    }
コード例 #10
0
ファイル: KimonoSketch.cs プロジェクト: yjpark/KimonoDesigner
        public NSImage ToImage()
        {
            // Get image data from sketch
            var skPngdata = Untitled1ToData();

            // Convert to image and return
            var data = NSData.FromBytes(skPngdata.Data, (nuint)skPngdata.Size);

            return(new NSImage(data));
        }
コード例 #11
0
    public void FromBytes()
    {
        byte[] bytes = new byte[] { 1, 2, 3, 4 };
        IntPtr ptr   = Marshal.AllocHGlobal(bytes.Length);

        Marshal.Copy(bytes, 0, ptr, bytes.Length);

        var data = NSData.FromBytes(ptr, (uint)bytes.Length);

        Assert.AreEqual(bytes.Length, data.Length);

        Marshal.FreeHGlobal(ptr);
    }
コード例 #12
0
ファイル: CGContextPDF.cs プロジェクト: zezba9000/maccore
        static void Add(NSMutableDictionary dict, IntPtr key, RectangleF?val)
        {
            if (!val.HasValue)
            {
                return;
            }
            NSData data;

            unsafe {
                RectangleF  f  = val.Value;
                RectangleF *pf = &f;
                data = NSData.FromBytes((IntPtr)pf, 16);
            }
            dict.LowlevelSetObject(data, key);
        }
コード例 #13
0
        public (NSArray <MPSImage> Inputs, NSArray <MPSState> Losses) GetRandomBatch(IMTLDevice device, int batchSize)
        {
            var trainImageDesc = MPSImageDescriptor.GetImageDescriptor(
                MPSImageFeatureChannelFormat.Unorm8,
                ImageSize, ImageSize, 1,
                1,
                MTLTextureUsage.ShaderWrite | MTLTextureUsage.ShaderRead);

            var trainBatch     = new List <MPSImage> ();
            var lossStateBatch = new List <MPSState> ();

            unsafe
            {
                fixed(byte *imagesPointer = imagesData)
                fixed(byte *labelsPointer = labelsData)
                {
                    for (var i = 0; i < batchSize; i++)
                    {
                        var randomIndex = random.Next(numImages);

                        var trainImage = new MPSImage(device, trainImageDesc)
                        {
                            Label = "TrainImage" + i
                        };
                        trainBatch.Add(trainImage);
                        var trainImagePointer = imagesPointer + ImagesPrefixSize + randomIndex * ImageSize * ImageSize;
                        trainImage.WriteBytes((IntPtr)trainImagePointer, MPSDataLayout.HeightPerWidthPerFeatureChannels, 0);

                        var labelPointer = labelsPointer + LabelsPrefixSize + randomIndex;
                        var labelsValues = new float[12];
                        labelsValues[*labelPointer] = 1;

                        fixed(void *p = labelsValues)
                        {
                            using var data = NSData.FromBytes((IntPtr)p, 12 * sizeof(float));
                            var desc = MPSCnnLossDataDescriptor.Create(
                                data, MPSDataLayout.HeightPerWidthPerFeatureChannels, new MTLSize(1, 1, 12));
                            var lossState = new MPSCnnLossLabels(device, desc);

                            lossStateBatch.Add(lossState);
                        }
                    }
                }
            }

            return(NSArray <MPSImage> .FromNSObjects(trainBatch.ToArray()),
                   NSArray <MPSState> .FromNSObjects(lossStateBatch.ToArray()));
        }
コード例 #14
0
        internal static SCNGeometry CreateVisualization(NVector3[] points, UIColor color, float size)
        {
            if (points.Length == 0)
            {
                return(null);
            }

            unsafe
            {
                var stride = sizeof(float) * 3;

                // Pin the data down so that it doesn't move
                fixed(NVector3 *pPoints = &points[0])
                {
                    // Grab a pointer to the data and treat it as a byte buffer of the appropriate length
                    var intPtr    = new IntPtr(pPoints);
                    var pointData = NSData.FromBytes(intPtr, (System.nuint)(stride * points.Length));

                    // Create a geometry source (factory) configured properly for the data (3 vertices)
                    var source = SCNGeometrySource.FromData(
                        pointData,
                        SCNGeometrySourceSemantics.Vertex,
                        points.Length,
                        true,
                        3,
                        sizeof(float),
                        0,
                        stride
                        );

                    // Don't unpin yet, because geometry creation is lazy

                    // Create geometry element
                    // The null and bytesPerElement = 0 look odd, but this is just a template object
                    var element = SCNGeometryElement.FromData(null, SCNGeometryPrimitiveType.Point, points.Length, 0);

                    element.PointSize = 0.001F;
                    element.MinimumPointScreenSpaceRadius = size;
                    element.MaximumPointScreenSpaceRadius = size;

                    // Stitch the data (source) together with the template (element) to create the new object
                    var pointsGeometry = SCNGeometry.Create(new[] { source }, new[] { element });

                    pointsGeometry.Materials = new[] { Utilities.Material(color) };
                    return(pointsGeometry);
                }
            }
        }
コード例 #15
0
        public override void OnStatusChange(GDHttpRequest httpRequest)
        {
            var state = httpRequest.GetState;

            switch (state)
            {
            case GDHttpRequestState.GDHttpRequestOpened:
                //Request opened so now send
                httpRequest.Send();
                break;

            case GDHttpRequestState.GDHttpRequestDone:
                //check status
                int status = httpRequest.GetStatus;

                if (status == 200)
                {
                    //the request has finished so see if we have any data
                    var buf     = httpRequest.GetReceiveBuffer;
                    var len     = buf.BytesUnread;
                    var rawData = new char[len];

                    //Marshal space for the buffer that will be used by the Good SDK
                    var dataPtr = new HandleRef(this, Marshal.StringToHGlobalAnsi(new string (rawData)));

                    buf.Read(dataPtr.Handle, len);
                    //rawData = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(dataPtr.Handle).ToCharArray();

                    //Transform into a NSData object
                    var data = NSData.FromBytes(dataPtr.Handle, (nuint)len);

                    if (data.Length > 0)
                    {
                        ParseData(data);
                    }
                    //Must clean up memory manually for Mashalled data or it will stick around forever
                    Marshal.FreeHGlobal(dataPtr.Handle);
                }
                break;
            }
            UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false;
        }
コード例 #16
0
        private async Task <Stream> GetAssetStream(string path)
        {
            Debug.WriteLine("MediaFile: GetAssetStream entered with path = {0}", (object)path);

            var streamCompletion = new TaskCompletionSource <Stream>();

            using (var rep = await GetAssetDefaultRepAsync(path))
            {
                // now some really ugly code to copy that as a byte array
                var size = (uint)rep.Size;
                //byte[] imgData = new byte[size];
                IntPtr  buffer = Marshal.AllocHGlobal((int)size);
                NSError bError;
                rep.GetBytes(buffer, 0, (uint)size, out bError);
                //Marshal.Copy(buffer, imgData, 0, imgData.Length);
                var imgData = NSData.FromBytes(buffer, (uint)size);
                Marshal.FreeHGlobal(buffer);
                return(imgData.AsStream());
            }
        }
コード例 #17
0
        public override void DidOutputSampleBuffer(AVCaptureOutput captureOutput, CMSampleBuffer sampleBuffer, AVCaptureConnection connection)
        {
            if (ready)
            {
                ready = false;
                CVPixelBuffer cVPixelBuffer = (CVPixelBuffer)sampleBuffer.GetImageBuffer();

                cVPixelBuffer.Lock(CVPixelBufferLock.ReadOnly);
                nint dataSize = cVPixelBuffer.DataSize;
                width  = cVPixelBuffer.Width;
                height = cVPixelBuffer.Height;
                IntPtr baseAddress = cVPixelBuffer.BaseAddress;
                bpr = cVPixelBuffer.BytesPerRow;
                cVPixelBuffer.Unlock(CVPixelBufferLock.ReadOnly);
                buffer = NSData.FromBytes(baseAddress, (nuint)dataSize);
                cVPixelBuffer.Dispose();
                queue.DispatchAsync(ReadTask);
            }
            sampleBuffer.Dispose();
        }
コード例 #18
0
        public static UIImage FromResource(Assembly assembly, string name)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }
            assembly = Assembly.GetCallingAssembly();
            var stream = assembly.GetManifestResourceStream(name);

            if (stream == null)
            {
                return(null);
            }

            IntPtr buffer = Marshal.AllocHGlobal((int)stream.Length);

            if (buffer == IntPtr.Zero)
            {
                return(null);
            }

            var    copyBuffer = new byte[Math.Min(1024, (int)stream.Length)];
            int    n;
            IntPtr target = buffer;

            while ((n = stream.Read(copyBuffer, 0, copyBuffer.Length)) != 0)
            {
                Marshal.Copy(copyBuffer, 0, target, n);
                target = (IntPtr)((int)target + n);
            }
            try
            {
                var data = NSData.FromBytes(buffer, (uint)stream.Length);
                return(UIImage.LoadFromData(data));
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
                stream.Dispose();
            }
        }
コード例 #19
0
        public static NSData FromResource(this Assembly assembly, string name)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }

            using (var stream = assembly.GetManifestResourceStream(name)) {
                if (stream == null)
                {
                    throw new SoftwareException("No embedded resource called '{0}' was found in assembly '{1}", name, assembly.FullName);
                }

                var buffer = Marshal.AllocHGlobal((int)stream.Length);
                try {
                    if (buffer == IntPtr.Zero)
                    {
                        return(null);
                    }

                    var copyBuffer = new byte[Math.Min(1024, (int)stream.Length)];
                    int n;
                    var target = buffer;
                    while ((n = stream.Read(copyBuffer, 0, copyBuffer.Length)) != 0)
                    {
                        Marshal.Copy(copyBuffer, 0, target, n);
                        target = (IntPtr)((int)target + n);
                    }
                    return((NSData)(NSData.FromBytes(buffer, (uint)stream.Length)));
                } finally {
                    if (buffer != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(buffer);
                    }
                }
            }
        }
コード例 #20
0
        public static Image LoadFromMemory(IntPtr pSource, int size, bool makeACopy, GCHandle?handle)
        {
            using (var imagedata = NSData.FromBytes(pSource, (uint)size))
                using (var cgImage = new UIImage(imagedata).CGImage)
                {
                    var image = Image.New2D((int)cgImage.Width, (int)cgImage.Height, 1, PixelFormat.R8G8B8A8_UNorm, 1, (int)cgImage.BytesPerRow);

                    using (var context = new CGBitmapContext(image.PixelBuffer[0].DataPointer, cgImage.Width, cgImage.Height, 8, cgImage.Width * 4, cgImage.ColorSpace, CGBitmapFlags.PremultipliedLast))
                    {
                        context.DrawImage(new RectangleF(0, 0, cgImage.Width, cgImage.Height), cgImage);

                        if (handle != null)
                        {
                            handle.Value.Free();
                        }
                        else if (!makeACopy)
                        {
                            Utilities.FreeMemory(pSource);
                        }

                        return(image);
                    }
                }
        }
コード例 #21
0
        internal NSData WriteStruct()
        {
            if (Sources?.Length > 0)
            {
                connectionParams.NumSources = (uint)Sources.Length;
                for (int i = 0; i < Sources.Length; i++)
                {
                    connectionParams.Sources[i] = Sources[i];
                }
            }

            if (Destinations?.Length > 0)
            {
                connectionParams.NumDestinations = (uint)Destinations.Length;
                for (int i = 0; i < Destinations.Length; i++)
                {
                    connectionParams.Destinations[i] = Destinations[i];
                }
            }

            if (ChannelMap?.Length > 0)
            {
                for (int i = 0; i < ChannelMap.Length; i++)
                {
                    connectionParams.ChannelMap[i] = ChannelMap[i];
                }
            }

            connectionParams.NumControlTransforms = Controls != null ? (ushort)Controls.Length : (ushort)0;
            connectionParams.NumMaps = Maps != null ? (ushort)Maps.Length : (ushort)0;

            var paramsSize   = Marshal.SizeOf(typeof(MidiThruConnectionParamsStruct));
            var controlsSize = Marshal.SizeOf(typeof(MidiControlTransform));
            // Get the full size of the struct, static + dynamic parts
            var fullSize = paramsSize +
                           (Controls == null ? 0 : controlsSize * Controls.Length) +
                           (Maps == null ? 0 : 128 * Maps.Length);
            var buffer    = Marshal.AllocHGlobal(fullSize);
            var bufferEnd = IntPtr.Add(buffer, Marshal.SizeOf(typeof(MidiThruConnectionParamsStruct)));

            try {
                // Copy static sized struct
                Marshal.StructureToPtr(connectionParams, buffer, false);

                if (connectionParams.NumControlTransforms > 0)
                {
                    unsafe {                     // Lets use memcpy to avoid a for loop
                        fixed(MidiControlTransform *arrAddr = &Controls[0])
                        Runtime.memcpy(bufferEnd, (IntPtr)arrAddr, controlsSize * connectionParams.NumControlTransforms);
                    }
                }

                if (connectionParams.NumMaps > 0)
                {
                    // Set the destination buffer after controls arr if any
                    bufferEnd = IntPtr.Add(bufferEnd, controlsSize * connectionParams.NumControlTransforms);
                    unsafe {                     // Lets use memcpy to avoid a for loop
                        for (int i = 0; i < connectionParams.NumMaps; i++)
                        {
                            fixed(byte *arrAddr = &Maps[i].Value[0])
                            Runtime.memcpy(bufferEnd, (IntPtr)arrAddr, 128);
                        }
                    }
                }

                var data = NSData.FromBytes(buffer, (nuint)fullSize);
                return(data);
            }
            finally {
                if (buffer != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(buffer);
                }
            }
        }
コード例 #22
0
        public bool Run(AlertDialogData data)
        {
            using (var alert = new NSAlert()) {
                if (data.Message.Icon == MonoDevelop.Ide.Gui.Stock.Information)
                {
                    alert.AlertStyle = NSAlertStyle.Critical;
                }
                else if (data.Message.Icon == MonoDevelop.Ide.Gui.Stock.Warning)
                {
                    alert.AlertStyle = NSAlertStyle.Warning;
                }
                else if (data.Message.Icon == MonoDevelop.Ide.Gui.Stock.Information)
                {
                    alert.AlertStyle = NSAlertStyle.Informational;
                }

                //FIXME: use correct size so we don't get horrible scaling?
                if (!string.IsNullOrEmpty(data.Message.Icon))
                {
                    var    pix = ImageService.GetPixbuf(data.Message.Icon, Gtk.IconSize.Dialog);
                    byte[] buf = pix.SaveToBuffer("tiff");
                    unsafe
                    {
                        fixed(byte *b = buf)
                        {
                            alert.Icon = new NSImage(NSData.FromBytes((IntPtr)b, (uint)buf.Length));
                        }
                    }
                }

                alert.MessageText     = data.Message.Text;
                alert.InformativeText = data.Message.SecondaryText ?? "";

                var buttons = data.Buttons.Reverse().ToList();

                for (int i = 0; i < buttons.Count - 1; i++)
                {
                    if (i == data.Message.DefaultButton)
                    {
                        var next = buttons[i];
                        for (int j = buttons.Count - 1; j >= i; j--)
                        {
                            var tmp = buttons[j];
                            buttons[j] = next;
                            next       = tmp;
                        }
                        break;
                    }
                }

                foreach (var button in buttons)
                {
                    var label = button.Label;
                    if (button.IsStockButton)
                    {
                        label = Gtk.Stock.Lookup(label).Label;
                    }
                    label = label.Replace("_", "");

                    //this message seems to be a standard Mac message since alert handles it specially
                    if (button == AlertButton.CloseWithoutSave)
                    {
                        label = GettextCatalog.GetString("Don't Save");
                    }

                    alert.AddButton(label);
                }


                NSButton[] optionButtons = null;
                if (data.Options.Count > 0)
                {
                    var box = new MDBox(LayoutDirection.Vertical, 2, 2);
                    optionButtons = new NSButton[data.Options.Count];

                    for (int i = data.Options.Count - 1; i >= 0; i--)
                    {
                        var option = data.Options[i];
                        var button = new NSButton()
                        {
                            Title = option.Text,
                            Tag   = i,
                            State = option.Value? NSCellStateValue.On : NSCellStateValue.Off,
                        };
                        button.SetButtonType(NSButtonType.Switch);
                        optionButtons[i] = button;
                        box.Add(new MDAlignment(button, true)
                        {
                            XAlign = LayoutAlign.Begin
                        });
                    }

                    box.Layout();
                    alert.AccessoryView = box.View;
                }

                NSButton applyToAllCheck = null;
                if (data.Message.AllowApplyToAll)
                {
                    alert.ShowsSuppressionButton = true;
                    applyToAllCheck       = alert.SuppressionButton;
                    applyToAllCheck.Title = GettextCatalog.GetString("Apply to all");
                }

                alert.Layout();

                int result = alert.RunModal() - (int)NSAlertButtonReturn.First;

                data.ResultButton = buttons [result];

                if (optionButtons != null)
                {
                    foreach (var button in optionButtons)
                    {
                        var option = data.Options[button.Tag];
                        data.Message.SetOptionValue(option.Id, button.State != 0);
                    }
                }

                if (applyToAllCheck != null && applyToAllCheck.State != 0)
                {
                    data.ApplyToAll = true;
                }

                GtkQuartz.FocusWindow(data.TransientFor ?? MessageService.RootWindow);
            }

            return(true);
        }
コード例 #23
0
ファイル: AppleExtensions.cs プロジェクト: zschong/SkiaSharp
        // NSData

        public static NSData ToNSData(this SKData skiaData)
        {
            return(NSData.FromBytes(skiaData.Data, (nuint)skiaData.Size));
        }
コード例 #24
0
        public bool Run(AlertDialogData data)
        {
            using (var alert = new NSAlert()) {
                alert.Window.Title = data.Title ?? BrandingService.ApplicationName;

                if (data.Message.Icon == MonoDevelop.Ide.Gui.Stock.Information)
                {
                    alert.AlertStyle = NSAlertStyle.Critical;
                }
                else if (data.Message.Icon == MonoDevelop.Ide.Gui.Stock.Warning)
                {
                    alert.AlertStyle = NSAlertStyle.Warning;
                }
                else                     //if (data.Message.Icon == MonoDevelop.Ide.Gui.Stock.Information) {
                {
                    alert.AlertStyle = NSAlertStyle.Informational;
                }

                //FIXME: use correct size so we don't get horrible scaling?
                if (!string.IsNullOrEmpty(data.Message.Icon))
                {
                    var    pix = ImageService.GetPixbuf(data.Message.Icon, Gtk.IconSize.Dialog);
                    byte[] buf = pix.SaveToBuffer("tiff");
                    unsafe
                    {
                        fixed(byte *b = buf)
                        {
                            alert.Icon = new NSImage(NSData.FromBytes((IntPtr)b, (uint)buf.Length));
                        }
                    }
                }
                else
                {
                    //for some reason the NSAlert doesn't pick up the app icon by default
                    alert.Icon = NSApplication.SharedApplication.ApplicationIconImage;
                }

                alert.MessageText     = data.Message.Text;
                alert.InformativeText = data.Message.SecondaryText ?? "";

                var buttons = data.Buttons.Reverse().ToList();

                for (int i = 0; i < buttons.Count - 1; i++)
                {
                    if (i == data.Message.DefaultButton)
                    {
                        var next = buttons[i];
                        for (int j = buttons.Count - 1; j >= i; j--)
                        {
                            var tmp = buttons[j];
                            buttons[j] = next;
                            next       = tmp;
                        }
                        break;
                    }
                }

                foreach (var button in buttons)
                {
                    var label = button.Label;
                    if (button.IsStockButton)
                    {
                        label = Gtk.Stock.Lookup(label).Label;
                    }
                    label = label.Replace("_", "");

                    //this message seems to be a standard Mac message since alert handles it specially
                    if (button == AlertButton.CloseWithoutSave)
                    {
                        label = GettextCatalog.GetString("Don't Save");
                    }

                    alert.AddButton(label);
                }


                NSButton[] optionButtons = null;
                if (data.Options.Count > 0)
                {
                    var box = new MDBox(LayoutDirection.Vertical, 2, 2);
                    optionButtons = new NSButton[data.Options.Count];

                    for (int i = data.Options.Count - 1; i >= 0; i--)
                    {
                        var option = data.Options[i];
                        var button = new NSButton()
                        {
                            Title = option.Text,
                            Tag   = i,
                            State = option.Value? NSCellStateValue.On : NSCellStateValue.Off,
                        };
                        button.SetButtonType(NSButtonType.Switch);
                        optionButtons[i] = button;
                        box.Add(new MDAlignment(button, true)
                        {
                            XAlign = LayoutAlign.Begin
                        });
                    }

                    box.Layout();
                    alert.AccessoryView = box.View;
                }

                NSButton applyToAllCheck = null;
                if (data.Message.AllowApplyToAll)
                {
                    alert.ShowsSuppressionButton = true;
                    applyToAllCheck       = alert.SuppressionButton;
                    applyToAllCheck.Title = GettextCatalog.GetString("Apply to all");
                }

                // Hack up a slightly wider than normal alert dialog. I don't know how to do this in a nicer way
                // as the min size constraints are apparently ignored.
                var frame = ((NSPanel)alert.Window).Frame;
                ((NSPanel)alert.Window).SetFrame(new RectangleF(frame.X, frame.Y, Math.Max(frame.Width, 600), frame.Height), true);
                alert.Layout();

                bool completed = false;
                if (data.Message.CancellationToken.CanBeCanceled)
                {
                    data.Message.CancellationToken.Register(delegate {
                        alert.InvokeOnMainThread(() => {
                            if (!completed)
                            {
                                NSApplication.SharedApplication.AbortModal();
                            }
                        });
                    });
                }

                if (!data.Message.CancellationToken.IsCancellationRequested)
                {
                    int result = alert.RunModal() - (int)NSAlertButtonReturn.First;
                    completed = true;
                    if (result >= 0 && result < buttons.Count)
                    {
                        data.ResultButton = buttons [result];
                    }
                    else
                    {
                        data.ResultButton = null;
                    }
                }

                if (data.ResultButton == null || data.Message.CancellationToken.IsCancellationRequested)
                {
                    data.SetResultToCancelled();
                }

                if (optionButtons != null)
                {
                    foreach (var button in optionButtons)
                    {
                        var option = data.Options[button.Tag];
                        data.Message.SetOptionValue(option.Id, button.State != 0);
                    }
                }

                if (applyToAllCheck != null && applyToAllCheck.State != 0)
                {
                    data.ApplyToAll = true;
                }

                GtkQuartz.FocusWindow(data.TransientFor ?? MessageService.RootWindow);
            }

            return(true);
        }