Unity3D draw GUI.Button over GUI.Window - c#

I want to draw a GUI Button on top of a GUI window that I have in my game, but no matter what I try the button always appears behind.
This is my Code:
GUI.depth = -30;
Rect navBackButton = new Rect(10, 10, 10, 10);
// DRAW NAVIGATION BUTTONS
if (GUI.Button(navBackButton, navBackButtonTexture))
{
// DO LOGIC HERE
}
GUI.depth = 10;
topScrollRect = new Rect(0, 0, Screen.width, topScrollHeight);
topScrollListSize = new Vector2(topScrollRect.width - 2*listMargin.x, topScrollRect.height - 2*listMargin.y);
GUI.skin.window = topStyle;
GUI.Window(0, topScrollRect, (GUI.WindowFunction)DoTopScrollWindow, "");
I have tried to draw the buttons before drawing the window, and the other way round, but both have the same result.
In this forum post (http://forum.unity3d.com/threads/setting-depth-of-a-window.12554/), it says that any GUI control with a depth of less than 1 will appear in front of GUI Windows, but I have set my depth to -30 and still the button appears behind the Window.
Any suggestions would be greatly appreciated!

The way to do this is to draw the button in DoTopScrollWindow().
You shouldn't try to place the buttons "on top" of the window, you should put them "in" the window, as the window is your navigation button's parent, conceptually. Additionally, drawing them in the window means that you can take advantage of relative positioning and window resizing without having to write a lot of extra code.
According to the docs, the parameter func in GUI.Window() is a function designed to display content inside the window.
In this case you want your buttons "inside" that window, so draw them in the function you pass in as func.

Related

How to place a label or a button exactly in the middle of the Form?

I can't find tools or properties to place a label or a button exactly in the middle of the Form. For example, on the X axis. VS 2015.
Design time :
In my VisualStudio2010 I have these 2 buttons to center horizontally and vertically:
Its located in the toolbar "Layout". If it isn't, you can add them by clicking the small button to the right. It is also in the Format menu.
To keep centered at Runtime: Turn off all anchoring.
Note:This will keep the control at its relative position as long as it doesn't change it Size. If it does, like autosize Labels are prone to, you will have to code the Resize event. Examples are here
For controls that may change in size, you need to catch the Resize event.
In my case I have a Panel, representing a page, inside another Panel which is the workspace. The workspace is set to autoscroll. In this scenario, it's important that the control is only centered when smaller than the container.
Whenever the form changes size or when I change the content, I call this function:
private void resetPagePos()
{
int wWS = pnlWorkspace.Width;
int hWS = pnlWorkspace.Height;
int wPage = pnlPage.Width;
int hPage = pnlPage.Height;
pnlPage.Location = new Point(Math.Max(0, (wWS - wPage) / 2), pnlPage.Top = Math.Max(0, (hWS - hPage) / 2));
}
The use of Math.Max(0, ...) makes sure that if the item doesn't fit, and the scrollbars are activates, then our page scrolls correctly. If the Left or Top are set to a negative number, you would get unwanted side-effects.

when i press tab the panel clears

Using DrawImageUnscaled my program draws a parobola or a line ...
If I press tab after the program draws, the panel in whith the image clears..
For my ox and oy axes i use ? and they disappear too...
System.Drawing.Pen linepen;
linepen = new System.Drawing.Pen(System.Drawing.Color.Green);
System.Drawing.Graphics g = drawingboard.CreateGraphics();
g.DrawLine(linepen, 0, drawingboard.Height / 2, drawingboard.Width, drawingboard.Height / 2);
g.DrawLine(linepen, drawingboard.Width / 2, 0, drawingboard.Width / 2, drawingboard.Height);
timer1.Enabled = false;
How can I fix this ?
Typically in DOT.NET you don't just paint what you want the user to see in a random place. Instead each panel (and control) has an OnPaint function which is called when the control displays itself. You want to modify this function to draw your new lines.
You will notice as you work with .NET that this function will get called multiple times when certain events happen in the application -- for example re-size. This allows the programmer to change what is displayed when the window changes size.
Add your code above to the OnPaint function of the control and it should work much better.
I'm not sure what you mean by ox and oy -- you don't seem to have any code with them

How can I make a background panel from a form transpart/invisible in an XNA window?

I have an XNA project that utilizes the Windows.Forms to create the GUI. Our GUI consists of a left panel and right panel. They both have a image laid over them(let's call them the panel images). Those images have buttons with images over them. Now the panel images don't completely cover the panel. Now what we want to do is make the panel invisible or transparent so you only see the panel images. In the picture below I circled what I want to be transparent/invisible. As you can see on the upper part of the project it already looks transparent but that is only because it blends in with the background on the XNA scene. On the bottom where the panel is over the ground you can see how the panel extends further than the panel images. So, does anyone know how I can make those parts invisible/transparent.
Alright, we've messed around with making the panel color Color.Transparent, magenta(XNA transparent color) and those attempts haven't worked. Any input/advice is welcome and much appreciated.
Here is the code that sets up the panel:
this.pnlLeftSide.BackgroundImage = global::Referenceator_UI.Resources.LeftBar;
this.pnlLeftSide.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.pnlLeftSide.Controls.Add(this.btnScreenShot);
this.pnlLeftSide.Controls.Add(this.btnScale);
this.pnlLeftSide.Controls.Add(this.btnMove);
this.pnlLeftSide.Controls.Add(this.btnRotate);
this.pnlLeftSide.Controls.Add(this.btnSelect);
this.pnlLeftSide.Location = new System.Drawing.Point(0, 0);
this.pnlLeftSide.Name = "pnlLeftSide";
this.pnlLeftSide.Size = new System.Drawing.Size(197, Screen.PrimaryScreen.WorkingArea.Height);
this.pnlLeftSide.Dock = DockStyle.Left;
this.pnlLeftSide.BackColor = controlColor; //this what we want invisible/transparent
-Thank you stackoverflow community
Try setting Region property of your panels. You can create necessary Region objects manually (by enumerating lines describing visible polygon) or use some method which converts image with transparency color key to Region (easily googled - https://stackoverflow.com/questions/886968/how-do-i-convert-an-images-transparency-into-a-region for example).
Since geometry of your panels does not seem to be too complex, you can create Region manually following way:
using(var gp = new System.Drawing.Drawing2D.GraphicsPath())
{
// Here goes series of AddLine() calls.
// You must
// gp.AddLine(0, 0, leftPanel.Width, 0);
// ...
gp.CloseFigure();
return new Region(gp);
}
Note that you'll get sharp edges with this method (even if it works). Consider rendering all that GUI using XNA.

Resizing a grid control programatically over a period of time

G'day,
I am attempting to simulate the old XBox 360 GUI with the sliding tabs (Remember, you'd press left or right and the content would slide in depending on the tab?) Anyways, at the moment, I have this working well, however I cannot get the "animation" working.
When the user presses left arrow or right arrow, my OpenWindow(int iIndex) method will be called, where iIndex is the index to the next or previous "window" to be slid in. (Not a window... each "Window" is a struct with a parent grid control containing a button and a smaller grid control that contains the windows contents.)
Now, my problem lies with resizing the parent grid control. When it is slid in, it is resized by calling mygrid.Width += 1; That works, but I don't see it happen over a determined period of time, it just lags a bit and then resizes to the required width. Whereas if I call this.Width += 1 in the same method, (this being the main program window) the window resizes how I want the grid control to resize. I've tried UpdateLayout() but to no avail. This tells me my timing is okay.
If anyone could be of assistance, it would be greatly appreciated.
Here is my OpenWindow method...
public void OpenWindow(int iIndex)
{
int iInterval = 1;
for (int i = (int)myDict[iIndex].Shell.Width; i < (int)stack_outter.Width; i += iInterval)
{
myDict[iIndex].Shell.Width += 1;
myDict[iIndex].Shell.UpdateLayout();
System.Threading.Thread.Sleep(1);
}
myDict[iIndex].Shell.Width = stack_outter.Width - (BUTTON_WIDTH * (myDict.Count - 1));
}
myDict is a Dictionary, Shell is the grid that I am attempting to animate when resizing. Sorry about the code, it's messy, my code is always hacked when I am trying to get stuff working :)
Thanks,
Ash
Neried Web Solutions
Your OpenWindow method is happening on the Dispatcher thread. That's also the thread responsible for rendering, so as long as your OpenWindow method doesn't return, nothing gets rendered.
The proper way to fix this would be to animate the Width property. I don't have any experience in starting animations from code (I've only used them in the past for things like a fade-in button highlight on mouse over, which is more easily done from WPF), but I took a quick read-through this page, Animation Overview on MSDN, and I think you'll want something like this:
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = myDict[iIndex].Shell.Width;
myDoubleAnimation.To = stack_outter.Width;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(0.5));
myDoubleAnimation.AutoReverse = false;
myDoubleAnimation.RepeatBehavior = new RepeatBehavior(1.0);
myStoryboard = new Storyboard();
myStoryboard.Children.Add(myDoubleAnimation);
Storyboard.SetTarget(myDoubleAnimation, myDict[iIndex].Shell);
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(FrameworkElement.WidthProperty));
myStoryboard.Begin(myDict[iIndex].Shell);

Fade between Tab Pages in a Tab Control

I have a Tab Control with multiple Tab Pages. I want to be able to fade the tabs back and forth. I don't see an opacity option on the Tab Controls. Is there a way to cause a fade effect when I switch from one Tab Page to another?
There is no magic Fade switch in the standard windows control.
You could dump the content of the tab to a bitmap (using DrawToBitmap or CopyFromScreen?), show that bitmap in front of the TabControl, switch tabs, and then fade the bitmap.
I decided to post what I did to get my solution working. GvS had the closest answer and sent me on my quest in the right direction so I gave him (might be a her, but come on) the correct answer check mark since I can't give it to myself.
I never did figure out how to "crossfade" from one tab to another (bring opacity down on one and bring opacity up on the other) but I found a wait to paint a grey box over a bitmap with more and more grey giving it the effect of fading into my background which is also grey. Then I start the second tab as a bitmap of grey that I slowly add less grey combined with the tab image each iteration giving it a fade up effect.
This solution leads to a nice fade effect (even if I do say so myself) but it is very linear. I am going to play a little with a Random Number Generator for the alphablend variable and see if that might make it a little less linear, but then again the users might appreciate the predictability. Btw, I fire the switch tab event with a button_click.
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
public int alphablend;
public Bitmap myBitmap;
private void button1_Click(object sender, EventArgs e)
{
alphablend = 0;
pictureBox1.Visible = true;
myBitmap = new Bitmap(tabControl1.Width, tabControl1.Height);
while (alphablend <= 246)
{
tabControl1.DrawToBitmap(myBitmap, new Rectangle(0, 0, tabControl1.Width, tabControl1.Height));
alphablend = alphablend + 10;
pictureBox1.Refresh();//this calls the paint action
}
tabControl1.SelectTab("tabPage2");
while (alphablend >= 0)
{
tabControl1.DrawToBitmap(myBitmap, new Rectangle(0, 0, tabControl1.Width, tabControl1.Height));
alphablend = alphablend - 10;
pictureBox1.Refresh();//this calls the paint action
}
pictureBox1.Visible = false;
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics bitmapGraphics = Graphics.FromImage(myBitmap);
SolidBrush greyBrush = new SolidBrush(Color.FromArgb(alphablend, 240, 240, 240));
bitmapGraphics.CompositingMode = CompositingMode.SourceOver;
bitmapGraphics.FillRectangle(greyBrush, new Rectangle(0, 0, tabControl1.Width, tabControl1.Height));
e.Graphics.CompositingQuality = CompositingQuality.GammaCorrected;
e.Graphics.DrawImage(myBitmap, 0, 0);
}
I don't see a specification of Winform/Webform, so I'll assume WebForm...
You can use an AJAX AnimationExtender.
Failing that, a bad way (which would work) would be to accept a QueryString that causes the page to auto-navigate to the tab you want, and use page Transitions.
For Winforms, you could use WPF :)
I don't believe that the WPF TabControl can be brought to fade from one TabItem to the next, since it is not equipped to display multiple TabItems simultaneously.
You could try to emulate this by stitching together two ListViews (one for the tab strip and one for the panel) and add the effect into the ControlTemplate of the latter. Use the ControlTemplates of the TabControl and the ListView as starting point.
Depending on how your tabs/page work, you may be able to handle it at the page level by adding meta tags to the page:
<meta http-equiv="Page-Enter" content="blendTrans(Duration=0)">
<meta http-equiv="Page-Exit" content="blendTrans(Duration=0)">
Just change the duration to make the fade longer or shorter. This is commonly referred to as FAJAX.

Categories

Resources