From 3b7858f96ad0b954e636cebfd1dcac2656374de1 Mon Sep 17 00:00:00 2001 From: elasota Date: Sat, 2 May 2020 01:51:32 -0400 Subject: [PATCH] Add support for map window resize in editor --- GpApp/Events.cpp | 8 +-- GpApp/Map.cpp | 33 +++++++++-- PortabilityLayer/PLCore.cpp | 52 +++++++++++++--- PortabilityLayer/PLCore.h | 6 +- PortabilityLayer/WindowManager.cpp | 95 +++++++++++++++++++++++++++++- PortabilityLayer/WindowManager.h | 4 ++ 6 files changed, 177 insertions(+), 21 deletions(-) diff --git a/GpApp/Events.cpp b/GpApp/Events.cpp index ce61dc6..f6fffe2 100644 --- a/GpApp/Events.cpp +++ b/GpApp/Events.cpp @@ -68,7 +68,7 @@ short BitchAboutColorDepth (void) void HandleMouseEvent (const GpMouseInputEvent &theEvent, uint32_t tick) { WindowPtr whichWindow; - long menuChoice, newSize; + long menuChoice; short thePart, hDelta, vDelta; Boolean isDoubleClick; Point evtPoint = Point::Create(theEvent.m_x, theEvent.m_y); @@ -110,11 +110,11 @@ void HandleMouseEvent (const GpMouseInputEvent &theEvent, uint32_t tick) } break; - case RegionIDs::kExpand: + case RegionIDs::kResize: if (whichWindow == mapWindow) { - newSize = GrowWindow(mapWindow, evtPoint, &thisMac.gray); - ResizeMapWindow(LoWord(newSize), HiWord(newSize)); + PortabilityLayer::Vec2i newSize = TrackResize(mapWindow, evtPoint, 47, 35, &thisMac.gray); + ResizeMapWindow(newSize.m_x, newSize.m_y); } break; diff --git a/GpApp/Map.cpp b/GpApp/Map.cpp index 8f93b3a..c450800 100644 --- a/GpApp/Map.cpp +++ b/GpApp/Map.cpp @@ -35,8 +35,8 @@ void LoadGraphicPlus (DrawSurface *, short, const Rect &); void RedrawMapContents (void); -void LiveHScrollAction (ControlHandle, short); -void LiveVScrollAction (ControlHandle, short); +void LiveHScrollAction (PortabilityLayer::Widget *theControl, int thePart); +void LiveVScrollAction (PortabilityLayer::Widget *theControl, int thePart); Boolean QueryNewRoom (void); void CreateNailOffscreen (void); void KillNailOffscreen (void); @@ -295,6 +295,29 @@ void RedrawMapContents (void) } #endif + +//-------------------------------------------------------------- UpdateMapWindow +void DrawMapResizeBox(void) +{ + DrawSurface *surface = &mapWindow->m_surface; + + const Rect windowRect = surface->m_port.GetRect(); + Rect growBoxRect = Rect::Create(windowRect.bottom - 14, windowRect.right - 14, windowRect.bottom, windowRect.right); + + surface->SetForeColor(PortabilityLayer::RGBAColor::Create(204, 204, 204, 255)); + surface->FillRect(growBoxRect); + + surface->SetForeColor(StdColors::Black()); + surface->FillRect(Rect::Create(growBoxRect.top + 2, growBoxRect.left + 2, growBoxRect.top + 3, growBoxRect.left + 6)); + surface->FillRect(Rect::Create(growBoxRect.top + 3, growBoxRect.left + 2, growBoxRect.top + 6, growBoxRect.left + 3)); + + surface->FillRect(Rect::Create(growBoxRect.top + 8, growBoxRect.left + 11, growBoxRect.top + 12, growBoxRect.left + 12)); + surface->FillRect(Rect::Create(growBoxRect.top + 11, growBoxRect.left + 8, growBoxRect.top + 12, growBoxRect.left + 11)); + + for (int i = 0; i < 7; i++) + surface->FillRect(Rect::Create(growBoxRect.top + 3 + i, growBoxRect.left + 3 + i, growBoxRect.top + 5 + i, growBoxRect.left + 5 + i)); +} + //-------------------------------------------------------------- UpdateMapWindow void UpdateMapWindow (void) @@ -311,6 +334,8 @@ void UpdateMapWindow (void) SetPortWindowPort(mapWindow); // PL_NotYetImplemented_TODO("Resize") RedrawMapContents(); + + DrawMapResizeBox(); #endif } @@ -339,12 +364,12 @@ void ResizeMapWindow (short newH, short newV) SizeWindow(mapWindow, mapWindowRect.right, mapWindowRect.bottom, true); mapHScroll->SetMax(kMaxNumRoomsH - mapRoomsWide); - mapHScroll->SetPosition(Point::Create(0, mapWindowRect.bottom - kMapScrollBarWidth + 1)); + mapHScroll->SetPosition(Point::Create(-1, mapWindowRect.bottom - kMapScrollBarWidth + 1)); mapHScroll->Resize(mapWindowRect.right - kMapScrollBarWidth + 3, kMapScrollBarWidth); mapLeftRoom = mapHScroll->GetState(); mapVScroll->SetMax(kMaxNumRoomsV - mapRoomsHigh); - mapVScroll->SetPosition(Point::Create(mapWindowRect.right - kMapScrollBarWidth + 1, 0)); + mapVScroll->SetPosition(Point::Create(mapWindowRect.right - kMapScrollBarWidth + 1, -1)); mapVScroll->Resize(kMapScrollBarWidth, mapWindowRect.bottom - kMapScrollBarWidth + 3); mapTopRoom = mapVScroll->GetState(); diff --git a/PortabilityLayer/PLCore.cpp b/PortabilityLayer/PLCore.cpp index ca87b1a..4641548 100644 --- a/PortabilityLayer/PLCore.cpp +++ b/PortabilityLayer/PLCore.cpp @@ -114,16 +114,52 @@ bool TrackGoAway(WindowPtr window, Point point) return false; } -Int32 GrowWindow(WindowPtr window, Point start, Rect *size) +PortabilityLayer::Vec2i TrackResize(WindowPtr window, Point start, uint16_t minWidth, uint16_t minHeight, Rect *size) { - PL_NotYetImplemented(); - return 0; -} + PortabilityLayer::WindowManager *wm = PortabilityLayer::WindowManager::GetInstance(); -bool TrackBox(WindowPtr window, Point point, int part) -{ - PL_NotYetImplemented(); - return false; + const Rect baseRect = window->m_surface.m_port.GetRect(); + + const PortabilityLayer::Vec2i baseSize = PortabilityLayer::Vec2i(baseRect.Width(), baseRect.Height()); + const PortabilityLayer::Vec2i basePoint = PortabilityLayer::Vec2i(start.h, start.v); + PortabilityLayer::Vec2i currentTarget = baseSize; + + wm->SetResizeInProgress(window, baseSize); + + for (;;) + { + TimeTaggedVOSEvent evt; + if (WaitForEvent(&evt, 1)) + { + if (evt.m_vosEvent.m_eventType == GpVOSEventTypes::kMouseInput) + { + const GpMouseInputEvent &mouseEvt = evt.m_vosEvent.m_event.m_mouseInputEvent; + + const PortabilityLayer::Vec2i nextPoint = PortabilityLayer::Vec2i(mouseEvt.m_x, mouseEvt.m_y); + PortabilityLayer::Vec2i requestedSize = baseSize + nextPoint - basePoint; + + if (requestedSize.m_x < static_cast(minWidth)) + requestedSize.m_x = minWidth; + + if (requestedSize.m_y < static_cast(minHeight)) + requestedSize.m_y = minHeight; + + if (requestedSize != currentTarget) + { + currentTarget = requestedSize; + wm->SetResizeInProgress(window, currentTarget); + } + + if (mouseEvt.m_button == GpMouseButtons::kLeft && mouseEvt.m_eventType == GpMouseEventTypes::kUp) + { + wm->ClearResizeInProgress(); + return requestedSize; + } + } + } + } + + return PortabilityLayer::Vec2i(0, 0); } WindowPtr GetNewCWindow(int resID, void *storage, WindowPtr behind) diff --git a/PortabilityLayer/PLCore.h b/PortabilityLayer/PLCore.h index 7aef823..506cd76 100644 --- a/PortabilityLayer/PLCore.h +++ b/PortabilityLayer/PLCore.h @@ -26,6 +26,7 @@ namespace PortabilityLayer struct MMHandleBlock; class IOStream; class Widget; + struct Vec2i; } typedef uint8_t Boolean; @@ -208,7 +209,7 @@ namespace RegionIDs kContent, kTitleBar, kClose, - kExpand, + kResize, }; } @@ -235,8 +236,7 @@ void Delay(int ticks, UInt32 *endTickCount); short FindWindow(Point point, WindowPtr *window); // Translates global coordinates to window coordinates, returns a region ID bool TrackGoAway(WindowPtr window, Point point); // Returns true if the close box was actually clicked (?) -Int32 GrowWindow(WindowPtr window, Point start, Rect *size); -bool TrackBox(WindowPtr window, Point point, int part); // Returns true if grow/shrink box was clicked (part corresponds to type) +PortabilityLayer::Vec2i TrackResize(WindowPtr window, Point start, uint16_t minWidth, uint16_t minHeight, Rect *size); WindowPtr GetNewCWindow(int resID, void *storage, WindowPtr behind); void SizeWindow(WindowPtr window, int width, int height, Boolean addToUpdateRegion); diff --git a/PortabilityLayer/WindowManager.cpp b/PortabilityLayer/WindowManager.cpp index ebce2e1..c972b17 100644 --- a/PortabilityLayer/WindowManager.cpp +++ b/PortabilityLayer/WindowManager.cpp @@ -119,6 +119,7 @@ namespace PortabilityLayer { public: WindowManagerImpl(); + ~WindowManagerImpl(); Window *CreateWindow(const WindowDef &windowDef) override; void ResizeWindow(Window *window, int width, int height) override; @@ -132,6 +133,9 @@ namespace PortabilityLayer void SetWindowTitle(Window *window, const PLPasStr &title) override; Rect2i GetWindowFullRect(Window *window) const override; + void SetResizeInProgress(Window *window, const PortabilityLayer::Vec2i &size) override; + void ClearResizeInProgress() override; + void RenderFrame(IGpDisplayDriver *displayDriver) override; void HandleScreenResolutionChange(uint32_t prevWidth, uint32_t prevHeight, uint32_t newWidth, uint32_t newHeight) override; @@ -144,9 +148,16 @@ namespace PortabilityLayer void RenderWindow(WindowImpl *window, IGpDisplayDriver *displayDriver); void DetachWindow(Window *window); + void ResetResizeInProgressSurfaces(); + WindowImpl *m_windowStackTop; WindowImpl *m_windowStackBottom; + Rect2i m_resizeInProgressRect; + DrawSurface m_resizeInProgressHorizontalBar; + DrawSurface m_resizeInProgressVerticalBar; + bool m_isResizeInProgress; + static WindowManagerImpl ms_instance; static uint8_t ms_putInFrontSentinel; @@ -219,9 +230,12 @@ namespace PortabilityLayer const DrawSurface *surface = window->GetDrawSurface(); const Rect rect = (*surface->m_port.GetPixMap())->m_rect; + const int32_t w = rect.Width(); + const int32_t h = rect.Height(); + if (window->GetStyleFlags() & WindowStyleFlags::kMiniBar) { - if (point.m_x >= 0 && point.m_x < rect.Width() && point.m_y < 0 && point.m_y >= -13) + if (point.m_x >= 0 && point.m_x < w && point.m_y < 0 && point.m_y >= -13) { outRegion = RegionIDs::kTitleBar; return true; @@ -229,13 +243,22 @@ namespace PortabilityLayer } else { - if (point.m_x >= 0 && point.m_x < rect.Width() && point.m_y < 0 && point.m_y >= -17) + if (point.m_x >= 0 && point.m_x < w && point.m_y < 0 && point.m_y >= -17) { outRegion = RegionIDs::kTitleBar; return true; } } + if (window->GetStyleFlags() & WindowStyleFlags::kResizable) + { + if (point.m_x >= w - 14 && point.m_x < w && point.m_y >= h - 14 && point.m_y < h) + { + outRegion = RegionIDs::kResize; + return true; + } + } + return false; } @@ -614,6 +637,12 @@ namespace PortabilityLayer WindowManagerImpl::WindowManagerImpl() : m_windowStackTop(nullptr) , m_windowStackBottom(nullptr) + , m_resizeInProgressRect(Rect2i(0, 0, 0, 0)) + , m_isResizeInProgress(false) + { + } + + WindowManagerImpl::~WindowManagerImpl() { } @@ -811,6 +840,48 @@ namespace PortabilityLayer return Rect2i(window->m_wmY - padding[WindowChromeSides::kTop], window->m_wmX - padding[WindowChromeSides::kLeft], window->m_wmY + portRect.Height() + padding[WindowChromeSides::kBottom], window->m_wmX + portRect.Width() + padding[WindowChromeSides::kRight]); } + void WindowManagerImpl::SetResizeInProgress(Window *window, const PortabilityLayer::Vec2i &size) + { + ResetResizeInProgressSurfaces(); + + m_isResizeInProgress = true; + if (!m_resizeInProgressHorizontalBar.Init(Rect::Create(0, 0, 3, size.m_x + 4), GpPixelFormats::k8BitStandard)) + { + m_resizeInProgressHorizontalBar.SetForeColor(StdColors::Black()); + m_resizeInProgressHorizontalBar.FillRect(Rect::Create(0, 0, 3, size.m_x + 4)); + m_resizeInProgressHorizontalBar.SetForeColor(StdColors::White()); + m_resizeInProgressHorizontalBar.FillRect(Rect::Create(1, 1, 2, size.m_x + 3)); + } + else + { + m_isResizeInProgress = false; + return; + } + + if (!m_resizeInProgressVerticalBar.Init(Rect::Create(0, 0, size.m_y, 3), GpPixelFormats::k8BitStandard)) + { + m_resizeInProgressVerticalBar.SetForeColor(StdColors::Black()); + m_resizeInProgressVerticalBar.FillRect(Rect::Create(0, 0, size.m_y, 1)); + m_resizeInProgressVerticalBar.FillRect(Rect::Create(0, 2, size.m_y, 3)); + m_resizeInProgressVerticalBar.SetForeColor(StdColors::White()); + m_resizeInProgressVerticalBar.FillRect(Rect::Create(0, 1, size.m_y, 2)); + } + else + { + m_isResizeInProgress = false; + return; + } + + const PortabilityLayer::Vec2i topLeft = PortabilityLayer::Vec2i(window->m_wmX, window->m_wmY); + m_resizeInProgressRect = PortabilityLayer::Rect2i(topLeft, topLeft + size); + } + + void WindowManagerImpl::ClearResizeInProgress() + { + ResetResizeInProgressSurfaces(); + m_isResizeInProgress = false; + } + void WindowManagerImpl::RenderFrame(IGpDisplayDriver *displayDriver) { PortabilityLayer::DisplayDeviceManager *dd = PortabilityLayer::DisplayDeviceManager::GetInstance(); @@ -823,6 +894,17 @@ namespace PortabilityLayer RenderWindow(window, displayDriver); window = window->GetWindowAbove(); } + + if (m_isResizeInProgress) + { + m_resizeInProgressHorizontalBar.PushToDDSurface(displayDriver); + m_resizeInProgressVerticalBar.PushToDDSurface(displayDriver); + + displayDriver->DrawSurface(m_resizeInProgressHorizontalBar.m_ddSurface, m_resizeInProgressRect.m_topLeft.m_x - 2, m_resizeInProgressRect.m_topLeft.m_y - 2, m_resizeInProgressRect.Right() - m_resizeInProgressRect.Left() + 4, 3); + displayDriver->DrawSurface(m_resizeInProgressHorizontalBar.m_ddSurface, m_resizeInProgressRect.m_topLeft.m_x - 2, m_resizeInProgressRect.m_bottomRight.m_y - 1, m_resizeInProgressRect.Right() - m_resizeInProgressRect.Left() + 4, 3); + displayDriver->DrawSurface(m_resizeInProgressVerticalBar.m_ddSurface, m_resizeInProgressRect.m_topLeft.m_x - 2, m_resizeInProgressRect.m_topLeft.m_y, 3, m_resizeInProgressRect.Bottom() - m_resizeInProgressRect.Top()); + displayDriver->DrawSurface(m_resizeInProgressVerticalBar.m_ddSurface, m_resizeInProgressRect.m_bottomRight.m_x - 1, m_resizeInProgressRect.m_topLeft.m_y, 3, m_resizeInProgressRect.Bottom() - m_resizeInProgressRect.Top()); + } } void WindowManagerImpl::HandleScreenResolutionChange(uint32_t prevWidth, uint32_t prevHeight, uint32_t newWidth, uint32_t newHeight) @@ -902,6 +984,15 @@ namespace PortabilityLayer impl->SetWindowBelow(nullptr); } + void WindowManagerImpl::ResetResizeInProgressSurfaces() + { + m_resizeInProgressHorizontalBar.~DrawSurface(); + m_resizeInProgressVerticalBar.~DrawSurface(); + + new (&m_resizeInProgressHorizontalBar) DrawSurface(); + new (&m_resizeInProgressVerticalBar) DrawSurface(); + } + Window *WindowManagerImpl::GetPutInFrontSentinel() const { return reinterpret_cast(&ms_putInFrontSentinel); diff --git a/PortabilityLayer/WindowManager.h b/PortabilityLayer/WindowManager.h index eb8e210..c07cd95 100644 --- a/PortabilityLayer/WindowManager.h +++ b/PortabilityLayer/WindowManager.h @@ -15,6 +15,7 @@ namespace PortabilityLayer { struct WindowDef; struct Rect2i; + struct Vec2i; class WindowManager { @@ -32,6 +33,9 @@ namespace PortabilityLayer virtual void SetWindowTitle(Window *window, const PLPasStr &title) = 0; virtual Rect2i GetWindowFullRect(Window *window) const = 0; + virtual void SetResizeInProgress(Window *window, const PortabilityLayer::Vec2i &size) = 0; + virtual void ClearResizeInProgress() = 0; + virtual void RenderFrame(IGpDisplayDriver *displayDriver) = 0; virtual void HandleScreenResolutionChange(uint32_t prevWidth, uint32_t prevHeight, uint32_t newWidth, uint32_t newHeight) = 0;