protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); mousePos = e.Location; if (dragging) { var players = profile.PlayerData; PlayerInfo player = players[draggingIndex]; Rectangle p = player.EditBounds; if (draggingScreen == -1) { for (int i = 0; i < screens.Length; i++) { UserScreen screen = screens[i]; Rectangle s = screen.UIBounds; float pc = RectangleUtil.PcInside(p, s); // bigger than 60% = major part inside this screen if (pc > 0.6f) { float offset = s.Width * 0.05f; // check if there's space available on this screen var playas = profile.PlayerData; Rectangle?editor; Rectangle?monitor; GetFreeSpace(i, out editor, out monitor); if (editor != null) { draggingScreenRec = editor.Value; draggingScreenBounds = monitor.Value; draggingScreen = i; } break; } } } else { Rectangle s = screens[draggingScreen].UIBounds; float pc = RectangleUtil.PcInside(p, s); if (pc < 0.6f) { draggingScreen = -1; } } p = new Rectangle(mousePos.X + draggingOffset.X, mousePos.Y + draggingOffset.Y, p.Width, p.Height); players[draggingIndex].EditBounds = p; Invalidate(); } }
protected override void OnMouseDoubleClick(MouseEventArgs e) { base.OnMouseDoubleClick(e); if (dragging) { return; } if (e.Button == MouseButtons.Left) { // first count how many gamepads we have bool changed = false; for (int i = 0; i < screens.Length; i++) { UserScreen screen = screens[i]; if (screen.UIBounds.Contains(e.Location) && !screen.SwapTypeBounds.Contains(e.Location)) { List <PlayerInfo> playerData = profile.PlayerData; // add all possible players! for (int j = 0; j < playerData.Count; j++) { PlayerInfo player = playerData[j]; Rectangle?editor; Rectangle?monitor; bool hasFreeSpace = GetFreeSpace(i, out editor, out monitor); if (hasFreeSpace) { if (player.ScreenIndex == -1) { player.Owner = screens[i]; player.ScreenIndex = i; player.MonitorBounds = monitor.Value; player.EditBounds = editor.Value; changed = true; } } else { break; } } break; } } if (changed) { UpdatePlayers(); } } }
private bool GetFreeSpace(int screenIndex, out Rectangle?editorBounds, out Rectangle?monitorBounds) { editorBounds = null; monitorBounds = null; var players = profile.PlayerData; UserScreen screen = screens[screenIndex]; Rectangle bounds = screen.MonitorBounds; Rectangle ebounds = screen.UIBounds; switch (screen.Type) { case UserScreenType.FullScreen: for (int i = 0; i < players.Count; i++) { PlayerInfo p = players[i]; if (p.ScreenIndex == screenIndex) { return(false); } } monitorBounds = screen.MonitorBounds; editorBounds = screen.UIBounds; return(true); case UserScreenType.DualHorizontal: { int playersUsing = 0; Rectangle areaUsed = new Rectangle(); for (int i = 0; i < players.Count; i++) { PlayerInfo p = players[i]; if (p.ScreenIndex == screenIndex) { playersUsing++; areaUsed = p.MonitorBounds; } } if (playersUsing == 2) { return(false); } int half = (int)(bounds.Height / 2.0f); for (int i = 0; i < 2; i++) { Rectangle area = new Rectangle(bounds.X, bounds.Y + (half * i), bounds.Width, half); if (!areaUsed.Contains(area)) { monitorBounds = area; int halfe = (int)(ebounds.Height / 2.0f); editorBounds = new Rectangle(ebounds.X, ebounds.Y + (halfe * i), ebounds.Width, halfe); return(true); } } } break; case UserScreenType.DualVertical: { int playersUsing = 0; Rectangle areaUsed = new Rectangle(); for (int i = 0; i < players.Count; i++) { PlayerInfo p = players[i]; if (p.ScreenIndex == screenIndex) { playersUsing++; areaUsed = p.MonitorBounds; } } if (playersUsing == 2) { return(false); } int half = (int)(bounds.Width / 2.0f); for (int i = 0; i < 2; i++) { Rectangle area = new Rectangle(bounds.X + (half * i), bounds.Y, half, bounds.Height); if (!areaUsed.Contains(area)) { monitorBounds = area; int halfe = (int)(ebounds.Width / 2.0f); editorBounds = new Rectangle(ebounds.X + (halfe * i), ebounds.Y, halfe, ebounds.Height); return(true); } } } break; case UserScreenType.FourPlayers: { int playersUsing = 0; for (int i = 0; i < players.Count; i++) { PlayerInfo p = players[i]; if (p.ScreenIndex == screenIndex) { playersUsing++; } } if (playersUsing == 4) { return(false); } int halfw = (int)(bounds.Width / 2.0f); int halfh = (int)(bounds.Height / 2.0f); for (int x = 0; x < 2; x++) { for (int y = 0; y < 2; y++) { Rectangle area = new Rectangle(bounds.X + (halfw * x), bounds.Y + (halfh * y), halfw, halfh); bool goNext = false; // check if there's any player with the area's x,y coord for (int i = 0; i < players.Count; i++) { PlayerInfo p = players[i]; if (p.ScreenIndex == screenIndex) { //if (p.MonitorBounds.X == area.X && // p.MonitorBounds.Y == area.Y) if (p.MonitorBounds.IntersectsWith(area)) { goNext = true; break; } } } if (goNext) { continue; } monitorBounds = area; int halfwe = (int)(ebounds.Width / 2.0f); int halfhe = (int)(ebounds.Height / 2.0f); editorBounds = new Rectangle(ebounds.X + (halfwe * x), ebounds.Y + (halfhe * y), halfwe, halfhe); return(true); } } } break; case UserScreenType.SixteenPlayers: { int playersUsing = 0; for (int i = 0; i < players.Count; i++) { PlayerInfo p = players[i]; if (p.ScreenIndex == screenIndex) { playersUsing++; } } if (playersUsing == 16) { return(false); } int halfw = (int)(bounds.Width / 4.0f); int halfh = (int)(bounds.Height / 4.0f); for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { Rectangle area = new Rectangle(bounds.X + (halfw * x), bounds.Y + (halfh * y), halfw, halfh); bool goNext = false; // check if there's any player with the area's x,y coord for (int i = 0; i < players.Count; i++) { PlayerInfo p = players[i]; if (p.ScreenIndex == screenIndex) { if (p.MonitorBounds.IntersectsWith(area)) { goNext = true; break; } } } if (goNext) { continue; } monitorBounds = area; int halfwe = (int)(ebounds.Width / 4.0f); int halfhe = (int)(ebounds.Height / 4.0f); editorBounds = new Rectangle(ebounds.X + (halfwe * x), ebounds.Y + (halfhe * y), halfwe, halfhe); return(true); } } } break; } return(false); }
private void UpdateScreens() { #if false if (screens == null) { screens = ScreensUtil.AllScreens(); totalBounds = RectangleUtil.Union(screens); } else { UserScreen[] newScreens = ScreensUtil.AllScreens(); Rectangle newBounds = RectangleUtil.Union(newScreens); if (newBounds.Equals(totalBounds)) { return; } // screens got updated, need to reflect in our window screens = newScreens; totalBounds = newBounds; // remove all players screens List <PlayerInfo> playerData = profile.PlayerData; if (playerData != null) { for (int i = 0; i < playerData.Count; i++) { PlayerInfo player = playerData[i]; player.EditBounds = GetDefaultBounds(draggingIndex); player.ScreenIndex = -1; } } } screensArea = new RectangleF(10, 50 + Height * 0.2f + 10, Width - 20, Height * 0.5f); float actualHeight = totalBounds.Height; float actualWidth = totalBounds.Width; if (actualWidth > actualHeight) { // horizontal monitor setup scale = screensArea.Width / actualWidth; if (totalBounds.Height * scale > screensArea.Height) { scale = screensArea.Height / actualHeight; } } else { // vertical monitor setup scale = screensArea.Height / actualHeight; if (totalBounds.Width * scale > screensArea.Width) { scale = screensArea.Width / actualWidth; } } Rectangle scaledBounds = RectangleUtil.Scale(totalBounds, scale); scaledBounds.X = (int)screensArea.X; scaledBounds.Y = (int)screensArea.Y; int minX = 0; int minY = 0; for (int i = 0; i < screens.Length; i++) { UserScreen screen = screens[i]; Rectangle bounds = RectangleUtil.Scale(screen.MonitorBounds, scale); Rectangle uiBounds = new Rectangle(bounds.X, bounds.Y + scaledBounds.Y, bounds.Width, bounds.Height); screen.UIBounds = uiBounds; minX = Math.Min(minX, bounds.X); minY = Math.Min(minY, bounds.Y); } // remove negative monitors minX = -minX; minY = -minY; for (int i = 0; i < screens.Length; i++) { UserScreen screen = screens[i]; Rectangle uiBounds = screen.UIBounds; uiBounds.X += minX + scaledBounds.X; uiBounds.Y += minY; screen.UIBounds = uiBounds; screen.SwapTypeBounds = RectangleUtil.Float(uiBounds.X, uiBounds.Y, uiBounds.Width * 0.1f, uiBounds.Width * 0.1f); } #endif }
protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; #if DEBUG //g.FillRectangle(Brushes.Green, playersArea); //g.FillRectangle(Brushes.CornflowerBlue, screensArea); //g.FillRectangle(Brushes.CornflowerBlue, new RectangleF(0, 0, Width, Height)); #endif UpdateScreens(); for (int i = 0; i < screens.Length; i++) { UserScreen s = screens[i]; g.DrawRectangle(lightWhitePen, s.UIBounds); g.DrawRectangle(lightWhitePen, s.SwapTypeBounds); switch (s.Type) { case Coop.UserScreenType.FullScreen: g.DrawImage(Resources.fullscreen, s.SwapTypeBounds); break; case Coop.UserScreenType.DualHorizontal: g.DrawImage(Resources.horizontal, s.SwapTypeBounds); break; case Coop.UserScreenType.DualVertical: g.DrawImage(Resources.vertical, s.SwapTypeBounds); break; case Coop.UserScreenType.FourPlayers: g.DrawImage(Resources._4players, s.SwapTypeBounds); break; case Coop.UserScreenType.SixteenPlayers: g.DrawImage(Resources._16players, s.SwapTypeBounds); break; } } var players = profile.PlayerData; if (players.Count == 0) { g.DrawString("No supported input devices connected", playerTextFont, Brushes.Red, new PointF(20, 40)); } else { for (int i = 0; i < players.Count; i++) { PlayerInfo info = players[i]; Rectangle s = info.EditBounds; g.ResetClip(); g.Clip = new Region(new RectangleF(s.X, s.Y, s.Width + 1, s.Height + 1)); Rectangle gamepadRect = RectangleUtil.ScaleAndCenter(gamepadImg.Size, s); string str = (i + 1).ToString(); SizeF size = g.MeasureString(str, playerFont); PointF loc = RectangleUtil.Center(size, s); if (info.IsXInput) { loc.Y -= gamepadRect.Height * 0.1f; GamepadButtonFlags flags = (GamepadButtonFlags)info.GamepadMask; //g.DrawString(flags.ToString(), smallTextFont, Brushes.White, new PointF(loc.X, loc.Y + gamepadRect.Height * 0.01f)); g.DrawString((info.GamepadId + 1).ToString(), playerFont, lightWhite, loc); g.DrawImage(gamepadImg, gamepadRect); } else if (info.IsKeyboardPlayer) { g.DrawImage(keyboardImg, gamepadRect); } else { loc.X = s.X; g.DrawString(info.GamepadName, playerTextFont, lightWhite, loc); g.DrawImage(genericImg, gamepadRect); } if (info.ScreenIndex != -1) { UserScreen screen = screens[info.ScreenIndex]; if ((s.Height + s.Y) - (screen.UIBounds.Height + screen.UIBounds.Y) == -1) { s.Height += 1; } g.Clip = new Region(new RectangleF(s.X, s.Y, s.Width + 1, s.Height + 1)); g.DrawRectangle(Pens.Green, s); } } } g.ResetClip(); if (dragging && draggingScreen != -1) { g.DrawRectangle(Pens.Red, draggingScreenRec); } g.DrawString("Input devices", playerTextFont, lightWhite, new PointF(10, 10)); SizeF dragEachGamepadSize; string dragEachGamepad = "Drag each device to a screen"; dragEachGamepad = StringUtil.WrapString(Width * 0.6f, dragEachGamepad, g, playerTextFont, out dragEachGamepadSize); g.DrawString(dragEachGamepad, playerTextFont, lightWhite, new PointF(Width - dragEachGamepadSize.Width, playersArea.Y)); SizeF bottomTextSize; string bottomText = "Click on screen's top-left corner to change players on that screen. Right click the player to change size"; bottomText = StringUtil.WrapString(Width - 20, bottomText, g, playerTextFont, out bottomTextSize); g.DrawString(bottomText, playerTextFont, lightWhite, new PointF(10, Height - bottomTextSize.Height - 10)); }
protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); var players = profile.PlayerData; if (dragging) { return; } if (e.Button == MouseButtons.Left) { for (int i = 0; i < screens.Length; i++) { UserScreen screen = screens[i]; if (screen.SwapTypeBounds.Contains(e.Location)) { if (screen.Type == Coop.UserScreenType.SixteenPlayers) { screen.Type = 0; } else { screen.Type++; } // invalidate all players inside screen for (int j = 0; j < players.Count; j++) { // return to default position PlayerInfo p = players[j]; if (p.ScreenIndex == i) { p.EditBounds = GetDefaultBounds(j); p.ScreenIndex = -1; } } Invalidate(); UpdatePlayers(); return; } } for (int i = 0; i < players.Count; i++) { Rectangle r = players[i].EditBounds; if (r.Contains(e.Location)) { dragging = true; draggingIndex = i; draggingOffset = new Point(r.X - e.X, r.Y - e.Y); Rectangle newBounds = GetDefaultBounds(draggingIndex); profile.PlayerData[draggingIndex].EditBounds = newBounds; if (draggingOffset.X < -newBounds.Width || draggingOffset.Y < -newBounds.Height) { draggingOffset = new Point(0, 0); } break; } } } else if (e.Button == MouseButtons.Right || e.Button == MouseButtons.Middle) { // if over a player on a screen, change the type for (int i = 0; i < players.Count; i++) { PlayerInfo p = players[i]; Rectangle r = p.EditBounds; if (r.Contains(e.Location)) { if (p.ScreenIndex != -1) { UserScreen screen = screens[p.ScreenIndex]; int halfWidth = screen.MonitorBounds.Width / 2; int halfHeight = screen.MonitorBounds.Height / 2; Rectangle bounds = p.MonitorBounds; if (screen.Type == Coop.UserScreenType.FourPlayers) { // check if the size is 1/4th of screen if (bounds.Width == halfWidth && bounds.Height == halfHeight) { bool hasLeftRightSpace = true; bool hasTopBottomSpace = true; // check if we have something left/right or top/bottom for (int j = 0; j < players.Count; j++) { if (i == j) { continue; } PlayerInfo other = players[j]; if (other.ScreenIndex != p.ScreenIndex) { continue; } if (other.MonitorBounds.Y == p.MonitorBounds.Y) { hasLeftRightSpace = false; } if (other.MonitorBounds.X == p.MonitorBounds.X) { hasTopBottomSpace = false; } if (other.MonitorBounds.X == screen.MonitorBounds.X + halfWidth && other.MonitorBounds.Height == screen.MonitorBounds.Height) { hasLeftRightSpace = false; } if (other.MonitorBounds.X == screen.MonitorBounds.X && other.MonitorBounds.Width == screen.MonitorBounds.Width) { hasTopBottomSpace = false; } } if (hasLeftRightSpace) { Rectangle edit = p.EditBounds; if (bounds.X == screen.MonitorBounds.X + bounds.Width) { bounds.X -= bounds.Width; edit.X -= edit.Width; } bounds.Width *= 2; edit.Width *= 2; p.EditBounds = edit; p.MonitorBounds = bounds; Invalidate(); } else if (hasTopBottomSpace) { Rectangle edit = p.EditBounds; if (bounds.Y == screen.MonitorBounds.Y + bounds.Height) { bounds.Y -= bounds.Height; edit.Y -= edit.Height; } bounds.Height *= 2; p.MonitorBounds = bounds; edit.Height *= 2; p.EditBounds = edit; Invalidate(); } } else { bounds.Width = screen.MonitorBounds.Width / 2; bounds.Height = screen.MonitorBounds.Height / 2; p.MonitorBounds = bounds; Rectangle edit = p.EditBounds; edit.Width = screen.UIBounds.Width / 2; edit.Height = screen.UIBounds.Height / 2; p.EditBounds = edit; Invalidate(); } } } } } } }