diff --git a/OpenDiablo2.Common/Interfaces/IMouseInfoProvider.cs b/OpenDiablo2.Common/Interfaces/IMouseInfoProvider.cs index 5568867e..76999cb9 100644 --- a/OpenDiablo2.Common/Interfaces/IMouseInfoProvider.cs +++ b/OpenDiablo2.Common/Interfaces/IMouseInfoProvider.cs @@ -12,5 +12,6 @@ namespace OpenDiablo2.Common.Interfaces int MouseY { get; } bool LeftMouseDown { get; } bool RightMouseDown { get; } + bool ReserveMouse { get; set; } } } diff --git a/OpenDiablo2.Common/Interfaces/IRenderWindow.cs b/OpenDiablo2.Common/Interfaces/IRenderWindow.cs index 208144ce..142e7994 100644 --- a/OpenDiablo2.Common/Interfaces/IRenderWindow.cs +++ b/OpenDiablo2.Common/Interfaces/IRenderWindow.cs @@ -15,6 +15,7 @@ namespace OpenDiablo2.Common.Interfaces void Update(); void Clear(); void Sync(); + void Quit(); ISprite LoadSprite(string resourcePath, string palette, Point location); ISprite LoadSprite(string resourcePath, string palette); IFont LoadFont(string resourcePath, string palette); diff --git a/OpenDiablo2.Core/UI/WideButton.cs b/OpenDiablo2.Core/UI/WideButton.cs index 4da69389..2ae52425 100644 --- a/OpenDiablo2.Core/UI/WideButton.cs +++ b/OpenDiablo2.Core/UI/WideButton.cs @@ -33,6 +33,8 @@ namespace OpenDiablo2.Core.UI private IFont font; private ILabel label; private bool pressed = false; + private bool active = false; // When true, button is actively being focus pressed + private bool activeLock = false; // When true, something else is being pressed so ignore everything private Point labelOffset = new Point(); private string text; @@ -69,7 +71,32 @@ namespace OpenDiablo2.Core.UI var hovered = (mouseInfoProvider.MouseX >= location.X && mouseInfoProvider.MouseX < (location.X + buttonWidth)) && (mouseInfoProvider.MouseY >= location.Y && mouseInfoProvider.MouseY < (location.Y + buttonHeight)); - pressed = hovered; + + if (!activeLock && hovered && mouseInfoProvider.LeftMouseDown && !mouseInfoProvider.ReserveMouse) + { + // The button is being pressed down + mouseInfoProvider.ReserveMouse = true; + active = true; + + } + else if (active && !mouseInfoProvider.LeftMouseDown) + { + mouseInfoProvider.ReserveMouse = false; + active = false; + + if (hovered) + OnActivate?.Invoke(); + } + else if (!active && mouseInfoProvider.LeftMouseDown) + { + activeLock = true; + } + else if (activeLock && !mouseInfoProvider.LeftMouseDown) + { + activeLock = false; + } + + pressed = (hovered && mouseInfoProvider.LeftMouseDown && active); } public void Render() diff --git a/OpenDiablo2.SDL2/SDL2RenderWindow.cs b/OpenDiablo2.SDL2/SDL2RenderWindow.cs index af915962..7c637160 100644 --- a/OpenDiablo2.SDL2/SDL2RenderWindow.cs +++ b/OpenDiablo2.SDL2/SDL2RenderWindow.cs @@ -17,13 +17,13 @@ namespace OpenDiablo2.SDL2_ private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private IntPtr window, renderer; - private bool running; - public bool IsRunning => running; + public bool IsRunning { get; private set; } public int MouseX { get; internal set; } = 0; public int MouseY { get; internal set; } = 0; public bool LeftMouseDown { get; internal set; } = false; public bool RightMouseDown { get; internal set; } = false; + public bool ReserveMouse { get; set; } = false; private readonly IMPQProvider mpqProvider; private readonly IPaletteProvider paletteProvider; @@ -52,9 +52,12 @@ namespace OpenDiablo2.SDL2_ SDL.SDL_ShowCursor(0); - running = true; + IsRunning = true; } + + public void Quit() => IsRunning = false; + public void Dispose() { SDL.SDL_DestroyRenderer(renderer); @@ -84,9 +87,35 @@ namespace OpenDiablo2.SDL2_ continue; } - if (evt.type == SDL.SDL_EventType.SDL_QUIT) + else if (evt.type == SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN) { - running = false; + switch((uint)evt.button.button) + { + case SDL.SDL_BUTTON_LEFT: + LeftMouseDown = true; + break; + case SDL.SDL_BUTTON_RIGHT: + RightMouseDown = true; + break; + } + } + + else if (evt.type == SDL.SDL_EventType.SDL_MOUSEBUTTONUP) + { + switch ((uint)evt.button.button) + { + case SDL.SDL_BUTTON_LEFT: + LeftMouseDown = false; + break; + case SDL.SDL_BUTTON_RIGHT: + RightMouseDown = false; + break; + } + } + + else if (evt.type == SDL.SDL_EventType.SDL_QUIT) + { + IsRunning = false; continue; } } diff --git a/OpenDiablo2.Scenes/MainMenu.cs b/OpenDiablo2.Scenes/MainMenu.cs index 72ff1238..45747189 100644 --- a/OpenDiablo2.Scenes/MainMenu.cs +++ b/OpenDiablo2.Scenes/MainMenu.cs @@ -28,7 +28,7 @@ namespace OpenDiablo2.Scenes private ISprite backgroundSprite, diabloLogoLeft, diabloLogoRight, diabloLogoLeftBlack, diabloLogoRightBlack; private IFont labelFont; private ILabel versionLabel, urlLabel; - private WideButton btnSinglePlayer; + private WideButton btnSinglePlayer, btnExit, btnWebsite; public MainMenu( IRenderWindow renderWindow, @@ -55,6 +55,17 @@ namespace OpenDiablo2.Scenes btnSinglePlayer = createWideButton(); btnSinglePlayer.Text = "Single Player".ToUpper(); btnSinglePlayer.Location = new Point(264, 290); + btnSinglePlayer.OnActivate = OnSinglePlayerClicked; + + btnWebsite = createWideButton(); + btnWebsite.Text = "Visible Github".ToUpper(); + btnWebsite.Location = new Point(264, 460); + btnWebsite.OnActivate = OnVisitWebsiteClicked; + + btnExit = createWideButton(); + btnExit.Text = "Exit Diablo II".ToUpper(); + btnExit.Location = new Point(264, 500); + btnExit.OnActivate = OnExitClicked; labelFont = renderWindow.LoadFont(ResourcePaths.Font16, Palettes.Static); versionLabel = renderWindow.CreateLabel(labelFont, new Point(50, 555), "v0.01 Pre-Alpha"); @@ -84,6 +95,9 @@ namespace OpenDiablo2.Scenes musicProvider.PlaySong(); } + private void OnVisitWebsiteClicked() + => System.Diagnostics.Process.Start("https://github.com/essial/OpenDiablo2/"); + public void Render() { // Render the background @@ -101,6 +115,8 @@ namespace OpenDiablo2.Scenes // Render the UI buttons btnSinglePlayer.Render(); + btnWebsite.Render(); + btnExit.Render(); //wideButton.Location = new Point(264, 290); //renderWindow.Draw(wideButton, 2, 1, 0); @@ -114,6 +130,8 @@ namespace OpenDiablo2.Scenes logoFrame -= 1f; btnSinglePlayer.Update(); + btnWebsite.Update(); + btnExit.Update(); } @@ -126,5 +144,10 @@ namespace OpenDiablo2.Scenes { } + + private void OnExitClicked() + { + renderWindow.Quit(); + } } }