473,396 Members | 2,147 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

moving a child window outside the bounding box of the parent window

HaLo2FrEeEk
404 256MB
I have an application that has 2 forms, a child and a parent. I want to make sure that the parent window can never be inside the child window in any way, so the code will need to check if any part of the parent window's bounding box is within the child window's bounding box. How can I accomplish this?

I tried this code:

Expand|Select|Wrap|Line Numbers
  1. if ((Owner.Top > this.Top) && (Owner.Top < this.Bottom + 10) && ((Owner.Left > this.Left) && (Owner.Left < this.Right + 10)))
  2. {
  3.     Owner.Top = this.Bottom + 10;
  4. }
But that only checks if the top left corner of the parent window is within the child window, not the whole thing. Is there any way to check the entire bounding box and see if there is any overlap?

As you can see with the code I'm using, if the parent is found to be within the child window, it puts it it at the bottom of the child window, plus 10 pixels. This poses a problem if the child window is moved to the bottom of the screen, which would cause the parent window to be pushed off the screen, so I'll also need to be able to check if the parent window is close to the screen border and perhaps put it above the child window instead of below.

There should also be something in place just in case the child window is expanded to the entire size of the screen, giving no room for the parent window, then it should allow the parent window to overlap the child window.
Jul 9 '10 #1
4 3956
GaryTexmo
1,501 Expert 1GB
Bounding box checking is fairly standard... Using this image...



You have containment...
IF
  • Bx >= Ax AND // Left > Left
  • Bx + Bw <= Ax + Aw AND // Right < Right
  • By >= Ay AND // Top > Top
  • By + Bh <= Ay + Ah // Bottom < Bottom

You have intersection...
IF
  • Bx <= Ax + Aw AND // Left < Right
  • Bx + Bw >= Ax AND // Right > Left
  • By <= Ay + Ah AND // Top < Bottom
  • By + Bh >= Ay // Bottom > Top

While this is easy enough to code, fortunately, Microsoft provides us a Rectangle class which will actually do the calculation for us in the System.Drawing namespace.

Here's a demo program...
Expand|Select|Wrap|Line Numbers
  1.     class Program
  2.     {
  3.         static void Main(string[] args)
  4.         {
  5.             RectangleObject A = new RectangleObject("A", 5, 5, 10, 10);
  6.             RectangleObject B = new RectangleObject("B", 7, 7, 10, 10);
  7.             RectangleObject C = new RectangleObject("C", 7, 7, 5, 5);
  8.             RectangleObject D = new RectangleObject("D", 20, 20, 10, 10);
  9.  
  10.             List<RectangleObject> rectList = new List<RectangleObject>();
  11.             rectList.AddRange(new RectangleObject[] { A, B, C, D });
  12.  
  13.             foreach (RectangleObject r1 in rectList)
  14.             {
  15.                 foreach (RectangleObject r2 in rectList)
  16.                 {
  17.                     if (r1 != r2)
  18.                     {
  19.                         if (r1.Contains(r2))
  20.                         {
  21.                             Console.WriteLine(r1 + " contains " + r2);
  22.                         }
  23.                         else
  24.                         {
  25.                             Console.WriteLine(r1 + " does not contain " + r2);
  26.                         }
  27.  
  28.                         if (r1.IntersectsWith(r2))
  29.                         {
  30.                             Console.WriteLine(r1 + " intersects with " + r2);
  31.                         }
  32.                         else
  33.                         {
  34.                             Console.WriteLine(r1 + " does not intersect with " + r2);
  35.                         }
  36.                     }
  37.                 }
  38.             }
  39.         }
  40.  
  41.         public class RectangleObject
  42.         {
  43.             public Rectangle Rectangle { get; set; }
  44.             public string Name { get; set; }
  45.  
  46.             public RectangleObject(string name, int x, int y, int width, int height)
  47.             {
  48.                 Name = name;
  49.                 Rectangle = new Rectangle(x, y, width, height);
  50.             }
  51.  
  52.             public bool IntersectsWith(RectangleObject rectObj)
  53.             {
  54.                 return Rectangle.IntersectsWith(rectObj.Rectangle);
  55.             }
  56.  
  57.             public bool Contains(RectangleObject rectObj)
  58.             {
  59.                 return Rectangle.Contains(rectObj.Rectangle);
  60.             }
  61.  
  62.             public override string ToString()
  63.             {
  64.                 return this.Name + ":" + string.Format("({0}, {1})-({2}, {3})", Rectangle.Left, Rectangle.Top, Rectangle.Right, Rectangle.Bottom);
  65.             }
  66.         }
  67.     }
Note: I only made the class so I could name the objects for easier reference :)

Also, and this is just as a fun suggestion, instead of putting it at a fixed position you could always place it a little more intelligently. You can get the vector between the two center points of the forms, then place the form along that vector at a position that puts the child form outside the parent form. What distance would that be? Well, imagine a circle contains each of your forms, what's the minimum radius of that circle? The longest distance from the center to the top-left or top-right corners. Then add that distance to the center distance of the other form and place it there. You can be a little more precise if you want to compare the lines that center vector intersects with (which is also more fun!) but the circle method is typically the simplest.

Aaaanyway, I digress. Hope that all helps!
Attached Images
File Type: jpg boxes.jpg (6.7 KB, 1717 views)
Jul 9 '10 #2
HaLo2FrEeEk
404 256MB
Ok, so I used this code to determine whether the child form contains or intersects with the parent form:

Expand|Select|Wrap|Line Numbers
  1. public void moveParentBox()
  2. {
  3.     Rectangle ownerRect = new Rectangle(Owner.Location, Owner.Size);
  4.     Rectangle thisRect = new Rectangle(this.Location, this.Size);
  5.  
  6.     if (thisRect.Contains(ownerRect))
  7.     {
  8.         Owner.BackColor = Color.Red;
  9.     } else if (thisRect.IntersectsWith(ownerRect))
  10.     {
  11.         Owner.BackColor = Color.Blue;
  12.     }
  13.     else
  14.     {
  15.         Owner.BackColor = Color.FromName("Control");
  16.     }
  17. }
And it seems to work. If I move the parent form partially within the child form, the background turns blue, if the parent form is fully within the child form, it turns red. If both return false the background color is reset. Since I don't need to detect each event by itself, only whether any part of the parent form is within the child form, I could condense it to this:

Expand|Select|Wrap|Line Numbers
  1. public void moveParentBox()
  2. {
  3.     Rectangle ownerRect = new Rectangle(Owner.Location, Owner.Size);
  4.     Rectangle thisRect = new Rectangle(this.Location, this.Size);
  5.  
  6.     if (thisRect.Contains(ownerRect) || thisRect.IntersectsWith(ownerRect))
  7.     {
  8.         Owner.BackColor = Color.Red;
  9.     }
  10.     else
  11.     {
  12.         Owner.BackColor = Color.FromName("Control");
  13.     }
  14. }
Now, I didn't get your second part. I think I understand the concept, but I can't seem to visualize the results you're going for with it. Can you help me better understand?

Also, thanks a ton for that rectangle tip, I wouldn't have found that out myself, I would have done it the hard way.
Jul 10 '10 #3
GaryTexmo
1,501 Expert 1GB
Glad you got it working! Bounding boxes are great... I've used them a lot, love 'em ;)

For that second part, it was more a way to move your window in a way that it would be a little more natural. How much do you know about vectors and vector math?

If nothing, here's the wikipedia: http://en.wikipedia.org/wiki/Euclidean_vector
(Note: That article makes it look a lot more complicated than it really is... but hopefully you can get something from it. Damn wiki elitists, making everything confusing ><)

This is a little more complex than I want to write up here... let me do a little example program using spheres when I get some time and I'll post it so you can see what I'm getting at.

I'll get back to you :)
Jul 10 '10 #4
GaryTexmo
1,501 Expert 1GB
Ok, here we go... it's a fair bit of code and I can't guarantee the best coding practices since I just threw it together, but it should be sufficient to get the idea ;)

Just drop the code into a new project with a windows form... ie, replace the code file generated by Visual Studio. My form size was 500x500, but you can do whatever you want I suppose.

Expand|Select|Wrap|Line Numbers
  1.     public partial class Form1 : Form
  2.     {
  3.         private List<Circle> m_objList = new List<Circle>();
  4.         private Circle m_circleGettingMoved = null;
  5.         private Vector m_offset = null;
  6.  
  7.         public Form1()
  8.         {
  9.             InitializeComponent();
  10.  
  11.             m_objList.Add(new Circle(new Vector(100, 100), 50, Color.Purple));
  12.             m_objList.Add(new Circle(new Vector(250, 150), 25, Color.Green));
  13.         }
  14.  
  15.         protected override void OnPaint(PaintEventArgs e)
  16.         {
  17.             base.OnPaint(e);
  18.  
  19.             Graphics g = e.Graphics;
  20.             foreach (Circle obj in m_objList)
  21.             {
  22.                 obj.Draw(g);
  23.             }
  24.         }
  25.  
  26.         private void Form1_MouseMove(object sender, MouseEventArgs e)
  27.         {
  28.             if (e.Button == MouseButtons.Left && m_circleGettingMoved != null)
  29.             {
  30.                 m_circleGettingMoved.Position = new Vector(e.X + m_offset.X, e.Y + m_offset.Y);
  31.                 this.Invalidate();
  32.             }
  33.         }
  34.  
  35.         private void Form1_MouseDown(object sender, MouseEventArgs e)
  36.         {
  37.             if (e.Button == MouseButtons.Left)
  38.             {
  39.                 if (m_circleGettingMoved == null)
  40.                 {
  41.                     Vector mousePoint = new Vector(e.Location.X, e.Location.Y);
  42.                     foreach (Circle circle in m_objList)
  43.                     {
  44.                         float dist = Vector.Distance(mousePoint, circle.Position);
  45.                         if (dist <= circle.Radius)
  46.                         {
  47.                             m_circleGettingMoved = circle;
  48.                             m_offset = new Vector(circle.Position.X - e.X, circle.Position.Y - e.Y);
  49.                             break;
  50.                         }
  51.                     }
  52.                 }
  53.             }
  54.         }
  55.  
  56.         private void Form1_MouseUp(object sender, MouseEventArgs e)
  57.         {
  58.             if (e.Button == MouseButtons.Left && m_circleGettingMoved != null)
  59.             {
  60.                 Circle moveCircle = m_circleGettingMoved;
  61.  
  62.                 foreach (Circle circle in m_objList)
  63.                 {
  64.                     if (circle != m_circleGettingMoved)
  65.                     {
  66.                         int totalDist = circle.Radius + moveCircle.Radius;
  67.                         if (Vector.Distance(circle.Position, moveCircle.Position) < totalDist)
  68.                         {
  69.                             Vector line = new Vector(moveCircle.Position.X - circle.Position.X, moveCircle.Position.Y - circle.Position.Y);
  70.                             line.Normalize();
  71.                             Vector newPos = new Vector(
  72.                                 circle.Position.X + totalDist * line.X,
  73.                                 circle.Position.Y + totalDist * line.Y);
  74.  
  75.                             moveCircle.Position.X = newPos.X;
  76.                             moveCircle.Position.Y = newPos.Y;
  77.                             this.Invalidate();
  78.                         }
  79.                     }
  80.                 }
  81.  
  82.                 m_circleGettingMoved = null;
  83.             }
  84.         }
  85.     }
  86.  
  87.     public class Vector
  88.     {
  89.         public float X { get; set; }
  90.         public float Y { get; set; }
  91.  
  92.         public Vector(float x, float y)
  93.         {
  94.             X = x;
  95.             Y = y;
  96.         }
  97.  
  98.         public static float Distance(Vector A, Vector B)
  99.         {
  100.             return (float)(Math.Sqrt((A.X - B.X) * (A.X - B.X) + (A.Y - B.Y) * (A.Y - B.Y)));
  101.         }
  102.  
  103.         public float Length()
  104.         {
  105.             return (float)(Math.Sqrt((X * X) + (Y * Y)));
  106.         }
  107.  
  108.         public void Normalize()
  109.         {
  110.             float absLength = Math.Abs(Length());
  111.             X = X / absLength;
  112.             Y = Y / absLength;
  113.         }
  114.  
  115.         public override string ToString()
  116.         {
  117.             return string.Format("(X={0}, Y={1})", X, Y);
  118.         }
  119.     }
  120.  
  121.     public interface IDrawableObject
  122.     {
  123.         Vector Position { get; set; }
  124.         void Draw(Graphics g);
  125.     }
  126.  
  127.     public class Circle : IDrawableObject
  128.     {
  129.         private Vector m_center;
  130.  
  131.         public Vector Center
  132.         {
  133.             get { return Position; }
  134.             set { Position = value; }
  135.         }
  136.  
  137.         public int Radius { get; set; }
  138.  
  139.         public Color Color
  140.         {
  141.             get { return m_pen.Color; }
  142.             set { m_pen.Color = value; }
  143.         }
  144.  
  145.         private Pen m_pen = new Pen(Color.Black);
  146.  
  147.         public Circle(Vector center, int radius, Color color)
  148.         {
  149.             Center = center;
  150.             Radius = radius;
  151.             m_pen.Color = color;
  152.         }
  153.  
  154.         #region IDrawableObject Members
  155.  
  156.         public void Draw(Graphics g)
  157.         {
  158.             if (g != null)
  159.             {
  160.                 g.DrawEllipse(m_pen, m_center.X - Radius, m_center.Y - Radius, Radius * 2, Radius * 2);
  161.             }
  162.         }
  163.  
  164.         public Vector Position
  165.         {
  166.             get
  167.             {
  168.                 return m_center;
  169.             }
  170.             set
  171.             {
  172.                 m_center = value;
  173.             }
  174.         }
  175.  
  176.         #endregion
  177.     }
I did this with circles and I'll leave it to you to figure out how to do it with rectangles. If you don't care about them meeting at the edges, you can just pretend the radius is the max of the width or the height, really.

Just run the code and click/hold to drag the circles around. Release the circle to stop dragging. If the circle overlaps the other, it will move outside along the direction between the centers.

This is a cheezy gdi implementation, so try not to judge me too harshly ;) Let me know if you have any questions!

*Edit: Oops! I just realized you'll need to manually hook up the events as well. They're appropriately named though so make sure you put the form events to the correct one.
Jul 11 '10 #5

Sign in to post your reply or Sign up for a free account.

Similar topics

4
by: dev1null2 | last post by:
Hi! I'm using window.open to create a secondary window, and everything is working fine with that. My problem is that as soon as that window is opened, the parent window scrolls to the top of...
1
by: Spammay Blockay | last post by:
Hi all... I'm writing a Struts application, and one window pops up another, non-modal, window. What I want to do is, when the user presses a button on the child window, I want the parent...
4
by: KenG | last post by:
Hi: I have a datagrid that builds a hyperling which uses javascript to open a new window. The new window opens and displays fine, however, the original window that has the grid, is now blank...
4
by: Sileesh | last post by:
Hi I have a btn in Parent.aspx page . On server_click() of the Btn, i am opening a new window called the child.apsx window. Child window also have a Btn. On serverClick of this Btn, I perform...
1
by: kebabkongen | last post by:
Hi, I am working on an application where I make a popup window with a long list of users (with checkboxes) I am trying to figure out how to pass the list of selected users to the parent window....
2
by: javanet | last post by:
Hi all, 1) i opened a parent window. 2) then i opend a child window thruogh this parent window. Now i want to close child window before closing the parend window means my clients can not be...
2
by: rishhi04 | last post by:
how to pass jsp child window value to parent jsp window .particular field or focus field
1
by: Bhishm | last post by:
Hi, I am opening a child window from parent using window.open, but on refreshing the parent the reference of the child is lost. Is there any way to save the reference of the child in the...
1
by: dummy07 | last post by:
Is it possible to close a modal window from the parent window??? Please help..
4
nitindel
by: nitindel | last post by:
Hi Guys... I am looking for a functionality of closing the POP UP window that i have opened from a Parent window....Whenver i Close the Parent window.. I mean to say... Whenver i close...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.