Release Update 06/24/2010

Here’s another major update for SQUID!

We completely revamped the samples, moved everything into one solution and included sample projects for Truevision3D, XNA3.1 and SlimDX. Added a few new controls, drag&drop and a brand new and slick looking style.

Screenshot of the code samples in action:

Release notes:

  • added TabControl
  • added HScrollBar control
  • added Panel control
  • added Drag & Drop
  • added SlimDX sample
  • added XNA 3.1 sample
  • added a completely new style
  • lots of bug fixes

Grab the new download HERE and have fun with it!

Posted in SQUID
13 Comments » for Release Update 06/24/2010
  1. Uncasid says:

    Fantastic! Glad to see this. I have teamed up with someone and we will be using your toolset. I will send you some screenshots when we get them together.

  2. uncasid says:

    Just an update.. Squid is hard to get working with XNA 4.0, you should have a tutorial for it

  3. Simon says:

    Thanks for that awesome library.
    It’s actually quite easy to get it working with XNA 4.0.
    Here’s the code I use to render the UI (I only had to modify a few methods)

    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework;
    
    namespace Core
    {
    	public class SquidRenderer
    		: DrawableGameComponent
    		, Squid.ISquidRenderer
    	{
    		Dictionary Fonts = new Dictionary();
    		Dictionary FontLookup = new Dictionary();
    
    		Dictionary Textures = new Dictionary();
    		Dictionary TextureLookup = new Dictionary();
    
    		Dictionary FontTypes = new Dictionary();
    
    		SpriteBatch Batch;
    
    		int FontIndex;
    		int TextureIndex;
    		Texture2D BlankTexture;
    
    		RasterizerState scissorState;
    		SamplerState samplerState;
    
    		public SquidRenderer(Game game)
    			: base(game)
    		{}
    
    		public override void Initialize()
    		{
    			base.Initialize();
    
    			Batch = new SpriteBatch(GraphicsDevice);
    
    			BlankTexture = new Texture2D(GraphicsDevice, 1, 1);
    			BlankTexture.SetData(new Color[] { new Color(255, 255, 255, 255) });
    
    			FontTypes.Add(Squid.Font.Default, new Squid.Font { Name = "Arial10", Family = "Arial", Size = 8, Bold = true, International = true });
    
    			scissorState = new RasterizerState();
    			scissorState.ScissorTestEnable = true;
    
    			samplerState = new SamplerState();
    			samplerState.Filter = TextureFilter.PointMipLinear;
    		}
    
    		private Color ColorFromtInt32(int color)
    		{
    			Byte[] bytes = BitConverter.GetBytes(color);
    
    			return new Color(bytes[2], bytes[1], bytes[0], bytes[3]);
    		}
    
    		public int GetTexture(string name)
    		{
    			if (TextureLookup.ContainsKey(name))
    				return TextureLookup[name];
    
    			Texture2D texture = Game.Content.Load("Textures\\Interface\\" + name);
    			TextureIndex++;
    
    			TextureLookup.Add(name, TextureIndex);
    			Textures.Add(TextureIndex, texture);
    
    			return TextureIndex;
    		}
    
    		public int GetFont(string name)
    		{
    			if (FontLookup.ContainsKey(name))
    				return FontLookup[name];
    
    			if (!FontTypes.ContainsKey(name))
    				return -1;
    
    			Squid.Font type = FontTypes[name];
    
    			SpriteFont font = Game.Content.Load("Fonts\\" + type.Name);
    			FontIndex++;
    
    			FontLookup.Add(name, FontIndex);
    			Fonts.Add(FontIndex, font);
    
    			return FontIndex;
    		}
    
    		public Squid.Point GetTextSize(string text, int font)
    		{
    			if (string.IsNullOrEmpty(text))
    				return new Squid.Point();
    
    			SpriteFont f = Fonts[font];
    			Vector2 size = f.MeasureString(text);
    			return new Squid.Point((int)size.X, (int)size.Y);
    		}
    
    		public Squid.Point GetTextureSize(int texture)
    		{
    			Texture2D tex = Textures[texture];
    			return new Squid.Point(tex.Width, tex.Height);
    		}
    
    		public void DrawBox(int x, int y, int w, int h, int color)
    		{
    			Rectangle destination = new Rectangle(x, y, w, h);
    			Batch.Draw(BlankTexture, destination, destination, ColorFromtInt32(color));
    		}
    
    		public void DrawText(string text, int x, int y, int font, int color)
    		{
    			if (!Fonts.ContainsKey(font))
    				return;
    
    			SpriteFont f = Fonts[font];
    			Batch.DrawString(f, text, new Vector2(x, y), ColorFromtInt32(color));
    		}
    
    		public void DrawTexture(int texture, int x, int y, int w, int h, Squid.UVCoords uv, int color)
    		{
    			if (!Textures.ContainsKey(texture))
    				return;
    
    			Texture2D tex = Textures[texture];
    
    			Rectangle destination = new Rectangle(x, y, w, h);
    			Rectangle source = new Rectangle();
    
    			source.X = (int)((float)(tex.Width) * uv.U1);
    			source.Y = (int)((float)(tex.Height) * uv.V1);
    			source.Width = (int)((float)(tex.Width * uv.U2)) - source.X;
    			source.Height = (int)((float)(tex.Height * uv.V2)) - source.Y;
    
    			Batch.Draw(tex, destination, source, ColorFromtInt32(color));
    		}
    
    		public void Scissor(int x1, int y1, int x2, int y2)
    		{
    			Rectangle rect = new Rectangle(x1, y1, x2 - x1, y2 - y1);
    			Game.GraphicsDevice.ScissorRectangle = rect;
    		}
    
    		public void StartBatch()
    		{
    			Batch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, samplerState, null, scissorState);
    		}
    
    		public void EndBatch()
    		{
    			Batch.End();
    		}
    	}
    }
    
  4. Dan says:

    How do I hook up a close event to the SampleWindow’s exit button?

  5.     public class SampleWindow : Window
        {
            public TitleBar Titlebar { get; private set; }
    
            protected override void Initialize()
            {
                base.Initialize();
    
                Padding = new Margin(7);
    
                Titlebar = new TitleBar();
                Titlebar.Dock = DockStyle.Top;
                Titlebar.Size = new Squid.Point(122, 35);
                Titlebar.OnMouseDown += delegate(Control sender) { StartDrag(); };
                Titlebar.OnMouseUp += delegate(Control sender) { StopDrag(); };
                Titlebar.Cursor = Cursors.Move;
                Titlebar.Style = "frame2";
                Titlebar.Margin = new Margin(0, 0, 0, -1);
                Titlebar.Button.OnMouseClick += Button_OnMouseClick;
                Controls.Add(Titlebar);
            }
    
            void Button_OnMouseClick(Control sender)
            {
                Close();
            }
        }
    
        public class TitleBar : Label
        {
            public Button Button { get; private set; }
    
            protected override void Initialize()
            {
                Button = new Button();
                Button.Size = new Point(30, 30);
                Button.Style = "button";
                Button.Tooltip = "Close Window";
                Button.Dock = DockStyle.Right;
                Button.Margin = new Margin(0, 8, 8, 8);
                Elements.Add(Button);
            }
        }
    
  6. Dan says:

    Thanks. I actually figured that solution out with some hacking. The other issue I am having is how to put a texture into the window? I really like SQUID UI and I like the layout, but there are a couple things I can’t figure out. Like I said, one is that I’d like to texture a control like a button. Is there a way to do this without access to the lower level code?

    I don’t want to just skin the control; I want to texture it.

  7. uncasid says:

    Hey, I have a pretty solid UI system that can be customized. I would like to give it to the squid community if you are interested.

  8. Yvan says:

    Hi. I’m new to Squid and it seems fairly straightforward to use for standard stuff.

    However, I’m having the same issue as Dan as I’m trying to create a simple RPG-style inventory and I want to be able to texture controls (e.g. buttons or panels for a backpack) with weapon and other textures which means I can’t just use the style settings. I had thought that I could subclass Squid’s Button class to include the extra texture (+ some functions for getting/setting it) and override the Draw function but it cannot be overriden. Any clues anyone???

  9. This is the most simple way to have a type of “PictureBox” control:

    public class ImageFrame : Control
    {
    
    public int Texture;
    
    protected override void DrawStyle(Style style, float opacity)
    {
    // uncomment this to draw the controls style as usual
    // base.DrawStyle(style, opacity);
    
    // we draw a texture on top
    GUI.Renderer.DrawTexture(Texture, Location.x, Location.y, Size.x, Size.y, new UVCoords(0, 0, 1, 1), -1);
    }
    }
    
  10. How to subclass Button and draw your own stuff:

    1. inherit Button
    2. override DrawStyle
    3. call base.DrawStyle to draw button as usual.
    4. draw your own things on top. you can use GUI.Renderer to do that.
    4. each control exposes a protected field called “Area”, which represents its screenspace rectangle, this is what you need to draw to the correct spot. (the code example above just uses location/size, which will not respect clipping. so better use the Area rectangle.

  11. Yvan says:

    Hi Christian,

    Thanks! That did the trick.

    Is there any reason why we have to store the extra textures I want to use in the TextureLookup dictionary before drawing them? I have a perfectly adequate asset management system in my project that grabs all assets from designated folders at startup (I’m not using the Content Manager built into XNA for this as I need the engine to be pluggable and I only need it to run on a PC).

    Since the GUI.Renderer.DrawTexture method requires a numeric texture id for the texture lookup as its first parameter, this means I effectively have to store the extra textures I want for my buttons twice, in both my asset system and yours, by rewriting GUI.Renderer.GetTexture somewhat. Any chance of changing this in a future release so that the GUI.Renderer.DrawTexture method is overloaded with the new additional version capable of sending a Texture2D object through as its first parameter?

    Or am I doing that wrong and there’s an easier way I’m missing? 8)

  12. Christian Herold says:

    @Yvan:
    Squid doesn’t use XNA or any other rendering engine directly, thus it doesn’t know about Texture2D. Your can completely change the way the renderer loads and stores textures, even integrate it with your own content management, but there will never be a Draw(Texture2D) call in Squid. It will always be an integer, because it is engine agnostic.

  13. uncasid says:

    “engine agnostic” haha, I love that term

Leave a Reply

Your email address will not be published.