using System; using Orvid.Graphics; namespace OForms.Windows { /// /// The class that represents the Taskbar. /// internal class Taskbar { /// /// The internal buffer of the taskbar. /// private Image Buffer; /// /// All of the windows in the taskbar. /// public Window[] Windows; /// /// The parent window manager of the taskbar. /// private WindowManager Manager; /// /// The location of the taskbar on the window manager. /// private Vec2 TaskbarLocation; /// /// The bounds of the taskbar. /// public BoundingBox Bounds; /// /// The color to clear the back of the taskbar with. /// public Pixel TaskbarClearColor = Colors.Coral; /// /// The color to outline the taskbar with. /// public Pixel TaskbarOutlineColor = Colors.Crimson; /// /// The color to draw an inactive window's back in. /// public Pixel WindowInactiveBackColor = Colors.Brown; /// /// The color to draw an inactive window's outline in. /// public Pixel WindowInactiveLineColor = Colors.Blue; /// /// The color to draw the active window's back in. /// public Pixel WindowActiveBackColor = Colors.Green; /// /// The color to draw the active window's outline in. /// public Pixel WindowActiveLineColor = Colors.Black; /// /// The color to draw the back of an over active window's back in. /// public Pixel WindowActiveOverBackColor = Colors.CadetBlue; /// /// The color to draw the back of an over inactive window's back in. /// public Pixel WindowInactiveOverBackColor = Colors.Chocolate; /// /// The default width of a button for a window. /// private const int WindowButtonWidth = 20; /// /// The margin around a window button. /// private const int WindowButtonMargin = 1; /// /// The height of the taskbar. /// public const int TaskBarHeight = 15; /// /// The bounds of all of the window buttons. /// internal BoundingBox[] WindowButtonBounds; /// /// The index of the button that the mouse is over. /// internal int overButtonIndx = 0; /// /// True if the over button has been drawn. /// private bool DrawnOverButton = false; /// /// True if the taskbar needs to be re-drawn. /// internal bool Modified = true; /// /// True if the mouse was over a window button. /// internal bool WasOverButton = false; /// /// True if the taskbar has been drawn since it was modified. /// private bool Drawn = false; /// /// The default constructor /// /// The parent window manager. public Taskbar(WindowManager mangr) { this.Windows = new Window[0]; this.Manager = mangr; this.Bounds = new BoundingBox(0, mangr.Size.X, mangr.Size.Y, mangr.Size.Y - TaskBarHeight); this.Buffer = new Image(mangr.Size.X, WindowManager.TaskBarHeight + 1); this.Buffer.Clear(TaskbarClearColor); this.WindowButtonBounds = new BoundingBox[0]; this.TaskbarLocation = new Vec2(0, Manager.Size.Y - TaskBarHeight); } /// /// Adds the specified window to the taskbar. /// /// The window to add. public void AddWindow(Window w) { Window[] tmp = new Window[Windows.Length + 1]; Array.Copy(Windows, tmp, Windows.Length); tmp[tmp.Length - 1] = w; Windows = tmp; Modified = true; Drawn = false; } /// /// Removes the specified window from the taskbar. /// /// The window to remove. public void RemoveWindow(Window w) { uint i; for (i = 0; i < Windows.Length; i++) { if (Windows[i] == w) { break; } } Window[] tmp = new Window[Windows.Length - 1]; Array.Copy(Windows, tmp, i); Array.Copy(Windows, i + 1, tmp, i, Windows.Length - i - 1); Windows = tmp; Modified = true; Drawn = false; } /// /// Redraws the Buffer. /// private void RedrawBuffer() { WindowButtonBounds = new BoundingBox[Windows.Length]; Buffer.Clear(TaskbarClearColor); int loc = 20; if (Windows.Length * (WindowButtonWidth + (2 * WindowButtonMargin)) < Manager.Size.X - 20) { #region No Dynamic Size Vec2 tl; Vec2 tr; Vec2 br; Vec2 bl; Window w; for (uint ind = 0; ind < Windows.Length; ind++) { w = Windows[ind]; tl = new Vec2( loc + WindowButtonMargin, (TaskBarHeight - (TaskBarHeight - 2 - WindowButtonMargin)) ); tr = new Vec2( loc + WindowButtonMargin + WindowButtonWidth, (TaskBarHeight - (TaskBarHeight - 2 - WindowButtonMargin)) ); br = new Vec2( loc + WindowButtonMargin + WindowButtonWidth, (TaskBarHeight - 2 - WindowButtonMargin) ); bl = new Vec2( loc + WindowButtonMargin, (TaskBarHeight - 2 - WindowButtonMargin) ); WindowButtonBounds[ind] = new BoundingBox( loc + WindowButtonMargin, loc + WindowButtonMargin + WindowButtonWidth, Manager.Size.Y - (TaskBarHeight - (TaskBarHeight - 2 - WindowButtonMargin)), Manager.Size.Y - (TaskBarHeight - 2 - WindowButtonMargin) ); if (w.IsActiveWindow && w.CurrentState != WindowState.Minimized) { Buffer.DrawRectangle(tl, br, WindowActiveBackColor); Buffer.DrawLines(new Vec2[] { tl, tr, br, bl, tl }, WindowActiveLineColor); } else { Buffer.DrawRectangle(tl, br, WindowInactiveBackColor); Buffer.DrawLines(new Vec2[] { tl, tr, br, bl, tl }, WindowInactiveLineColor); } loc += WindowButtonMargin + WindowButtonMargin + WindowButtonWidth; } #endregion } else { #region Dynamic Size uint len = (uint)Manager.Size.X - 20; int ButtonWidth = (int)Math.Floor((double)((len / Windows.Length) - 2)); if (ButtonWidth > 5) { Vec2 tl; Vec2 tr; Vec2 br; Vec2 bl; Window w; for (uint ind = 0; ind < Windows.Length; ind++) { w = Windows[ind]; tl = new Vec2( loc + WindowButtonMargin, (TaskBarHeight - (TaskBarHeight - 2 - WindowButtonMargin)) ); tr = new Vec2( loc + WindowButtonMargin + ButtonWidth, (TaskBarHeight - (TaskBarHeight - 2 - WindowButtonMargin)) ); br = new Vec2( loc + WindowButtonMargin + ButtonWidth, (TaskBarHeight - 2 - WindowButtonMargin) ); bl = new Vec2( loc + WindowButtonMargin, (TaskBarHeight - 2 - WindowButtonMargin) ); WindowButtonBounds[ind] = new BoundingBox( loc + WindowButtonMargin, loc + WindowButtonMargin + ButtonWidth, Manager.Size.Y - (TaskBarHeight - (TaskBarHeight - 2 - WindowButtonMargin)), Manager.Size.Y - (TaskBarHeight - 2 - WindowButtonMargin) ); if (w.IsActiveWindow && w.CurrentState != WindowState.Minimized) { Buffer.DrawRectangle(tl, br, WindowActiveBackColor); Buffer.DrawLines(new Vec2[] { tl, tr, br, bl, tl }, WindowActiveLineColor); } else { Buffer.DrawRectangle(tl, br, WindowInactiveBackColor); Buffer.DrawLines(new Vec2[] { tl, tr, br, bl, tl }, WindowInactiveLineColor); } loc += WindowButtonMargin + WindowButtonMargin + ButtonWidth; } } else { Buffer.DrawRectangle(new Vec2(24, 4), new Vec2(Buffer.Width - 10, Buffer.Height - 4), Colors.Cyan); } #endregion } Modified = false; Drawn = true; } /// /// Draws the taskbar on the specified image. /// /// The image to draw on. public void Draw(Image i) { if (Modified) { RedrawBuffer(); } i.DrawImage(TaskbarLocation, Buffer); Drawn = true; } /// /// Undraws the over WindowButton. /// /// Bounds of the window to undraw. /// The window to undraw. internal void UndrawOverButton(BoundingBox bounds, Window w) { Vec2 tl = new Vec2(bounds.Left, bounds.Bottom) - TaskbarLocation; Vec2 tr = new Vec2(bounds.Right, bounds.Bottom) - TaskbarLocation; Vec2 br = new Vec2(bounds.Right, bounds.Top) - TaskbarLocation; Vec2 bl = new Vec2(bounds.Left, bounds.Top) - TaskbarLocation; if (w.IsActiveWindow && w.CurrentState != WindowState.Minimized) { Buffer.DrawRectangle(tl, br, WindowActiveBackColor); Buffer.DrawLines(new Vec2[] { tl, tr, br, bl, tl }, WindowActiveLineColor); } else { Buffer.DrawRectangle(tl, br, WindowInactiveBackColor); Buffer.DrawLines(new Vec2[] { tl, tr, br, bl, tl }, WindowInactiveLineColor); } WasOverButton = false; } /// /// Draws the over WindowButton. /// /// The bounds of the window to draw. /// The window to draw. private void DrawOverButton(BoundingBox bounds, Window w) { Vec2 tl = new Vec2(bounds.Left, bounds.Bottom) - TaskbarLocation; Vec2 tr = new Vec2(bounds.Right, bounds.Bottom) - TaskbarLocation; Vec2 br = new Vec2(bounds.Right, bounds.Top) - TaskbarLocation; Vec2 bl = new Vec2(bounds.Left, bounds.Top) - TaskbarLocation; if (w.IsActiveWindow && w.CurrentState != WindowState.Minimized) { Buffer.DrawRectangle(tl, br, WindowActiveOverBackColor); Buffer.DrawLines(new Vec2[] { tl, tr, br, bl, tl }, WindowActiveLineColor); } else { Buffer.DrawRectangle(tl, br, WindowInactiveOverBackColor); Buffer.DrawLines(new Vec2[] { tl, tr, br, bl, tl }, WindowInactiveLineColor); } WasOverButton = true; } /// /// Processes the mouse move event. /// /// Location of the mouse. internal void DoMouseMove(Vec2 loc) { if (!Drawn) { RedrawBuffer(); } if (!WasOverButton) { for (int i = 0; i < Windows.Length; i++) { if (WindowButtonBounds[i].IsInBounds(loc)) { DrawOverButton(WindowButtonBounds[i], Windows[i]); overButtonIndx = i; return; } } } else { if (WindowButtonBounds[overButtonIndx].IsInBounds(loc) || !DrawnOverButton) { UndrawOverButton(WindowButtonBounds[overButtonIndx], Windows[overButtonIndx]); for (int i = 0; i < Windows.Length; i++) { if (WindowButtonBounds[i].IsInBounds(loc)) { DrawOverButton(WindowButtonBounds[i], Windows[i]); overButtonIndx = i; return; } } overButtonIndx = 0; DrawnOverButton = true; return; } } } /// /// Processes a click event. /// /// The location of the mouse. /// The buttons that are pressed. internal void DoClick(Vec2 loc, MouseButtons buttons) { if (!Drawn) { RedrawBuffer(); } if (WasOverButton) { if (WindowButtonBounds[overButtonIndx].IsInBounds(loc)) { if (Windows[overButtonIndx].IsActiveWindow) { Manager.MinimizeWindow(Windows[overButtonIndx]); } else if (Windows[overButtonIndx].CurrentState == WindowState.Minimized) { Manager.RestoreWindow(Windows[overButtonIndx]); } else { Manager.BringWindowToFront(Windows[overButtonIndx]); } DrawnOverButton = false; DoMouseMove(loc); } else { for (int i = 0; i < Windows.Length; i++) { if (WindowButtonBounds[i].IsInBounds(loc)) { DrawOverButton(WindowButtonBounds[i], Windows[i]); overButtonIndx = i; DrawnOverButton = false; if (Windows[i].IsActiveWindow) { Manager.MinimizeWindow(Windows[i]); } else if (Windows[i].CurrentState == WindowState.Minimized) { Manager.RestoreWindow(Windows[i]); } else { Manager.BringWindowToFront(Windows[i]); } DoMouseMove(loc); return; } } } } else { for (int i = 0; i < Windows.Length; i++) { if (WindowButtonBounds[i].IsInBounds(loc)) { DrawOverButton(WindowButtonBounds[i], Windows[i]); overButtonIndx = i; DrawnOverButton = false; if (Windows[i].IsActiveWindow) { Manager.MinimizeWindow(Windows[i]); } else if (Windows[i].CurrentState == WindowState.Minimized) { Manager.RestoreWindow(Windows[i]); } else { Manager.BringWindowToFront(Windows[i]); } DoMouseMove(loc); return; } } } } } }