MonoGame.Forms - Create your Editor Environment!

Guys,

This ā€œshowcaseā€ thread has turned into a stream of issues.

Iā€™m not the maintainer of this project so I could be completely out of line here but it seems to me that itā€™d be better to be posting issues about the project on github rather than in this thread.

That way, each issue could be discussed individually and closed when itā€™s no longer an issue.

Just my two cents.

5 Likes

Hello I am here - I already tried to fix for Gtk Sharp 3.x for Windows but it looks very bright - It doesnā€™t make normal color.

using Cairo;
using Gtk;
using System;

namespace MonoGame.Framework.Gtk3
{
    public class RenderArea : DrawingArea
    {
        private Cairo.Color _clearColor;
        private Microsoft.Xna.Framework.Graphics.Viewport _view;
        public event EventHandler Rendered;

        public RenderArea()
        {
            BackgroundColor = BackgroundColor;
            _view = new Microsoft.Xna.Framework.Graphics.Viewport(0, 0, Allocation.Width, Allocation.Height);

            Rendered += new EventHandler(OnRender);
            Drawn += new DrawnHandler(drawnHandler);
        }

        protected virtual void OnRender(object sender, EventArgs e)
        {
        }

        private void drawnHandler(object o, DrawnArgs args)
        {
            Context cr = args.Cr;
            PointD p1, p2, p3, p4;
            p1 = new PointD(0, 0);
            p2 = new PointD(Allocation.Width, 0);
            p3 = new PointD(Allocation.Width, Allocation.Height);
            p4 = new PointD(0, Allocation.Height);

            cr.MoveTo(p1);
            cr.LineTo(p2);
            cr.LineTo(p3);
            cr.LineTo(p4);
            cr.LineTo(p1);
            cr.ClosePath();

#pragma warning disable CS0612 // Type or member is obsolete
#pragma warning disable CS0618 // Type or member is obsolete
            cr.Color = _clearColor;
            cr.FillPreserve();
            Surface surf = Surface.CreateForImage(Format.Argb32, Allocation.Width, Allocation.Height);
            cr.SetSourceSurface(surf, 0, 0);

            Gtk3Backend.BeginDraw(Allocation.Width, Allocation.Height);

            Gtk3Backend.GraphicsDevice.Clear(new Microsoft.Xna.Framework.Color((byte)_clearColor.R, (byte)_clearColor.G, (byte)_clearColor.B, (byte)_clearColor.A));

            Gtk3Backend.GraphicsDevice.Viewport = _view;

            Rendered?.Invoke(o, EventArgs.Empty);

            Gtk3Backend.EndDraw();
            Gdk.CairoHelper.SetSourceWindow(cr, GdkWindow, 0, 0);
            cr.Paint();
            cr.GetTarget().Dispose();
            cr.GetTarget().Destroy();
#pragma warning restore CS0618 // Type or member is obsolete
#pragma warning restore CS0612 // Type or member is obsolete
        }

        protected override void OnSizeAllocated(Gdk.Rectangle allocation)
        {
            _view = new Microsoft.Xna.Framework.Graphics.Viewport(allocation.X, allocation.Y, allocation.Width, allocation.Height);
            base.OnSizeAllocated(allocation);
        }

        protected override void Dispose(bool disposing)
        {
            Destroy();
            base.Dispose(disposing);
        }

        public Color BackgroundColor
        {
            get
            {
                return _clearColor;
            }

            set
            {
                _clearColor = new Color(value.R, value.G, value.B, value.A);
            }
        }
    }
}

I already tried with Present() But it is really hard to resolve ā€¦ I have any possiblities and Gtk.Dotnet.Graphics.fromDrawable()

// EDIT:

From RenderArea.cs:

protected override bool OnDrawn(Context cr)
{
    PointD p1, p2, p3, p4;
    p1 = new PointD(0, 0);
    p2 = new PointD(Allocation.Width, 0);
    p3 = new PointD(Allocation.Width, Allocation.Height);
    p4 = new PointD(0, Allocation.Height);

    cr.MoveTo(p1);
    cr.LineTo(p2);
    cr.LineTo(p3);
    cr.LineTo(p4);
    cr.LineTo(p1);
    cr.ClosePath();

#pragma warning disable CS0612 // Type or member is obsolete
#pragma warning disable CS0618 // Type or member is obsolete
cr.Color = _clearColor;
cr.FillPreserve();
Surface surf = Surface.CreateForImage(Format.Argb32, Allocation.Width, Allocation.Height);
cr.SetSourceSurface(surf, 0, 0);

    Gtk3Backend.BeginDraw(Allocation.Width, Allocation.Height);

    Gtk3Backend.GraphicsDevice.Clear(new Microsoft.Xna.Framework.Color((byte)_clearColor.R, (byte)_clearColor.G, (byte)_clearColor.B, (byte)_clearColor.A));

    Gtk3Backend.GraphicsDevice.Viewport = _view;

    Rendered?.Invoke(null, EventArgs.Empty);

    Gtk3Backend.EndDraw();
    Gdk.CairoHelper.SetSourceWindow(cr, GdkWindow, 0, 0);
    cr.Paint();

    System.Drawing.Graphics graphics = Gtk.DotNet.Graphics.FromDrawable(GdkWindow);
    graphics.DrawImage(Gtk3Backend.Present(), 0, 0, Allocation.Width, Allocation.Height);
    cr.GetTarget().Dispose();
    cr.GetTarget().Destroy();

#pragma warning restore CS0618 // Type or member is obsolete
#pragma warning restore CS0612 // Type or member is obsolete
return base.OnDrawn(cr);
}

Gtk3Backend.cs ( in MasterWindow )

I add someting lines for support with Cairo.

    internal void EndRender()
    {
        // Exit if not drawing anything
        if (!isDrawing) return;

        // Create Surface Image
        var width = DeviceManager.PreferredBackBufferWidth;
        var height = DeviceManager.PreferredBackBufferHeight;

        var bmp = new Bitmap(width, height, PixelFormat.Format32bppRgb);
        var bmpData = bmp.LockBits(
            new System.Drawing.Rectangle(0, 0, width, height),
            ImageLockMode.WriteOnly,
            PixelFormat.Format32bppRgb);
        var pixelData = new int[width * height];

        // Get buffer data
        GraphicsDevice.GetBackBufferData(pixelData);
        for (int i = 0; i < pixelData.Length; i++)

#pragma warning disable // Caused by bitwise function requiring uint to int conversion
pixelData[i] = (int)( // Swap bgra - rgba
(pixelData[i] & 0x000000ff) << 16 |
(pixelData[i] & 0x0000FF00) |
(pixelData[i] & 0x00FF0000) >> 16 |
(pixelData[i] & 0xFF000000));
#pragma warning disable

        // Convert to bitmap
        Cairo.Context cr;
        Cairo.ImageSurface imgsrf = new Cairo.ImageSurface(bmpData.Scan0,
        Cairo.Format.Argb32, width, height, width * 4);
        cr = new Cairo.Context(imgsrf);
        Marshal.Copy(pixelData, 0, bmpData.Scan0, pixelData.Length);
        bmp.UnlockBits(bmpData);
        BackBuffer = bmp;

        // Mark as done drawing.
        isDrawing = false;
    } 

Result: NotsupportedException :frowning:

So close my success :confused: I wish that Gtk Sharp 3.x works like Winforms

// EDIT. I tried Gtk.Bin but Gtk.Bin is same like Gtk.DrawingArea
Gtk.Widget or Gtk.Container are quick closing gtk App. :frowning:

Thanks my great witch! Welcome in our community! Please donā€™t convert us as frogs!

Nice job hehe I will try for Gtk Sharp 3.2 I know far onExposedEvent for Gtk Sharp 2.x and onDrawn for Gtk Sharp 3.x

Nice work! But why do you need WinForms? Timer. Donā€™t need with WinForms.

Just without Timer - I already tested with Gtk Sharp 3 = It works fine 100 % Wow I have replaced:

onExposedEvent to onDrawn
Dispose to Destory

PS: Why do you not use Cairo.Color or Gdk.RGBA?

It is okay for that. I wish I need extra features

Timer removed I donā€™t need - It works fine.

Fixing point for Gtk Sharp 3 without Timer - Please use Timeout of Gtk Sharp because it support like Timeout

That is why not using Timer of WinForms.

But for me without.

I will write later. I am still supervising.

Now download you can download this from mega.nz

Please remember your work like me! You should write pure c# not stetic! Because stetic of Gtk Sharp 2 or 3 are not good. That is why you need write pure C#. It is better to understand like my code:

public MyClass()
{
  Title = "My Class Hello Window";
  ...
}

Remember quiting of Gtk Sharp is "DeleteEvent += OnDeleteEventHandler;

than you can write sometimes:

private void onDeleteEventHandler(object o, DeleteEventArgs args)
{
    Application.Quit();
    Environment.Exit(-1);
}

// EDIT Yeaaaah Timer is for WinForms and for Gtk Sharp need custom Timer as GLibTimer.cs I have writtenā€¦
Updated Zip in same file!

GLibTimer.cs:

using System;

namespace Game1.Source
{
    public delegate void TimerElapsedHandler(object sender, TimerElapsedEventArgs args);

    public class TimerElapsedEventArgs : EventArgs
    {
        DateTime signalTime;

        public TimerElapsedEventArgs()
        {
            signalTime = DateTime.Now;
        }
    }

    public class GLibTimer
    {
        private bool _enabled;
        public bool enabled
        {
            get
            {
                return _enabled;
            }
            set
            {
                _enabled = value;
                if (_enabled)
                    Start();
                else
                    Stop();
            }
        }
        protected uint timerId;

        public event TimerElapsedHandler TimerElapsedEvent;
        public uint TimerInterval;
        public bool autoReset;

        public GLibTimer() : this(0) { }

        public GLibTimer(uint timerInterval)
        {
            _enabled = false;
            TimerInterval = timerInterval;
            autoReset = true;
            timerId = 0;
        }

        public void Start()
        {
            _enabled = true;
            timerId = GLib.Timeout.Add(TimerInterval, OnTimeout);
        }

        public void Stop()
        {
            _enabled = false;
            GLib.Source.Remove(timerId);
        }

        protected bool OnTimeout()
        {
            if (_enabled)
            {
                if (TimerElapsedEvent != null)
                    TimerElapsedEvent(this, new TimerElapsedEventArgs());
            }
            return _enabled & autoReset;
        }
    }
}

Yay I am happy now. I know how does it fix like same hehehe.

// EDIT: Now it replaced Timer for Gtk Sharp like WinForms :smiley: But

Tick = TimerElapsedEvent
Enabled = enabled
inverval = TimerInterval

Now I have added interval into RenderWidget :smiley:

Yay Updated to mega.nz Yay!

God thanks for resolving - Haha @SpiceyWolf canā€™t magicia that :smiley:

I have hacked to poor magician @SpiceyWolf and have resolved :smiley:

I am happy now. Juhuuu!

// Updated feature with Linux Ubuntu 18.04 appends same Userinterface Yay

1 Like

I used the MonoGame/Xna color since it had to be set manually (No point in adding the extra conversion step for the widget color when you wont ever see the color in a visual designer ā€“ its just extra variables) as well I wasnt familiar with GTK timer system it seemed overly complex when I can just import a Winforms Timer (It runs in background anyway). The timer system was needed to control the update intervals so you can have SOME control over the performance as if its updating as often as GTK tries to make it happen it literally Updates constantly without end so for example the animation example i did ended up ALWAYS running at the same speed for all controls and animating extremely quickly. Thats lost performance AND makes more work to correct for without how i did the timer at the same timeā€¦

Also that one guy was right we shouldnt be taking over the thread, Ima go through and pull my irrelevant stuff (Only leaving the GTK and Winforms controls here as reference ā€“ and sqrMin1 can make do em better if they ever get updates that provide useful info to him) I recommend you pull yours too just to cleanup the mess we made on this thread. (Happy to remove the links if you dont want them referenced here anymore @BlizzCrafter)

Github: https://github.com/SpiceyWolf/MonoGame.Framework.Winforms
Github: https://github.com/SpiceyWolf/MonoGame.Framework.Gtk

2 Likes

Wait you forget to fix Timer under Gtk ( your https://github.com/SpiceyWolf/MonoGame.Framework.Gtk is for Gtk Sharp 2

My new repository is for Gtk Sharp 3.22.x Please remember that! @BlizzCrafter Please add my reference for Gtk Sharp 3.22. to your MonoGame.GtkSharp ( ā€œā€¦Gtkā€ by @SpiceyWolf and ā€œā€¦Gtk3ā€ by @Jens_Eckervogt ( ME ) and ā€œā€¦Winformsā€ by @SpiceyWolf to MonoGame.Forms or do you like together?
https://github.com/sourceskyboxer/MonoGame.Framework.Gtk3

Thanks!

If ur on Github you can fork and send a PR to me and ill just take it :open_mouth: -> Throw a credits.txt and put both our names in it tho if u do xD

I forgot I am sorry that I will fix ā€¦

UPDATE
https://github.com/sourceskyboxer/MonoGame.Framework.Gtk3/blob/master/Credit.txt

Update now Nuget: https://www.nuget.org/packages/MonoGame.Framework.Gtk3/0.1.0

@SpiceyWolf Can you give me the MonoGame.Framework.Gtk id? Proper Gtk widget support incomingā€¦

1 Like

Basically I need to agree with @craftworkgames that we are about to lose the overview in this thread.

Think of people discovering this topic which contains ā€œMonoGame.Formsā€ in the headline and experiencing a stream of Gtk issues and they donā€™t really know whatā€™s happening or why this topic is listed in the ā€œShowcaseā€ category.

So, when having a bigger feature idea and needing to discuss it more deeply (issues etc), then here is a much more elegant solution for the future:

  1. Small discussion about the new feature here in this thread.
  2. Creating a new topic about the new feature in the MonoGame forum (Community Area)
  3. In the first post of the newly created topic place a link to this thread, which connects the two topics internally and makes them visible in each topic (scroll to the top of this thread to see an example of already connected topics [on the right hand side of the first post]).
  4. When you are done with the new feature from the new topic, share the result by creating a reply in this thread with a link to the corresponding post showing the milestone (also GitHub links are very welcome).

This should make everthing clearer for us and new or returning visitors.

Donā€™t get me wrong: Iā€™m very happy about your effort in making the library better and it makes me proud that we are gathered here to create something awesome!

Further more itā€™s still allowed to have small discussions or requests here as long as they are have something to do with MonoGame.Forms (respectivly parts of the MonoGame.Framwork itself).

(I wish I could somehow pin this rules here)


I will also take a look at the Gtk implementations but in the moment my time is very limited. So donā€™t expect it to soon.

Until then: Thank you all for your effort!


Just placing a link to the GitHub repo here for new users to make it easier for them to find the library:

Keep up the good work and have a nice weekend!

1 Like

Also just delete ur past posts relating to the issues -> They are non issues now and irrelevant to the thread :open_mouth: in 12 hours the thread could be cleared up of our mess :smiley: well myne is already gone anyhow >.>

Edit: Oops thought that i hit that reply to Jens ā€“ @Jens_Eckervogt do what i said above lol

Edit: Since ur probably seeing this Sqrā€¦ I has myself a theory on how to possibly correct the solution with the bitmap to something a little less gross >.> Ill get back with you probably tomorrow on if it works outā€¦

Because you canā€™t grab nuget ids unless you upload something.

Just FYI, I have Gtk version working locally, donā€™t think Iā€™ve mentioned it above:

Its directly rendering to Gtk GLArea, plus custom implementations for Input/Window and some other stuff.

3 Likes

PR 2 of 3 is up: https://github.com/MonoGame/MonoGame/pull/6378

Wow your great implementer how did you get successful with GLArea i already tried before but it doesnā€™t see sprites? How did you implement?

Full source code is available at the link above.

Hello @harry-cpp where is full source . I donā€™t see where is link. You mean Post: 118

But It looks only githubā€™s issue.

// EDIT You are right.

How do I add renderWindow? Why do you call RenderWindow? What does it mean? I thought you add Gtk Button like I saw your picture. How did you? I want know. Why do you say my net framework horrible? But It is as ā€œAreaā€ not ā€œWindowā€.

MonoGame.Forms 2.1.0 - Audio Support

  • Now updating the FrameworkDispatcher to enable Audio in MonoGame.Forms [DX; GL].
  • Create SoundEffects, SoundEffectInstances and Songs, and play them using the MonoGame.Framework.
  • RenderTargets created with the RenderTargetManager are now enabled on creation, so they are becoming available without the need of resizing a control first [DX].

I remembering that someone here wanted to create a GameBoy Emulator with MonoGame.Forms. This audio update should be very useful :wink:

You could also create a MediaPlayer now or load and preview audio fles in your editor.

Happy Coding! :smiley:

And where is other method by @harry-cpp ?

I wait longer 2 months ā€¦

I will take a closer look when the PR got merged.

Further I need to implement it differently, because MonoGame.Forms does not make use of the game class.

Iā€™m also busy with a different project, which I will reveal soon.

Thanks for understanding.

Iā€™m having an issue where whenever I move my mouse over a DrawWindow in my project, the scroll bar for the form containing it automatically resets. I was able to find that somebody on stackoverflow had the same issue but the thread was deleted. Is this a common issue with an easy solution?