diff --git a/GpApp/Map.cpp b/GpApp/Map.cpp index 4414331..a566f03 100644 --- a/GpApp/Map.cpp +++ b/GpApp/Map.cpp @@ -327,20 +327,20 @@ void ResizeMapWindow (short newH, short newV) if (mapRoomsHigh < 3) mapRoomsHigh = 3; QSetRect(&mapWindowRect, 0, 0, - mapRoomsWide * kMapRoomWidth + kMapScrollBarWidth - 2, - mapRoomsHigh * kMapRoomHeight + kMapScrollBarWidth - 2); + mapRoomsWide * kMapRoomWidth + kMapScrollBarWidth - 1, + mapRoomsHigh * kMapRoomHeight + kMapScrollBarWidth - 1); surface->SetForeColor(StdColors::White()); surface->FillRect(mapWindowRect); SizeWindow(mapWindow, mapWindowRect.right, mapWindowRect.bottom, true); mapHScroll->SetMax(kMaxNumRoomsH - mapRoomsWide); - mapHScroll->SetPosition(Point::Create(0, mapWindowRect.bottom - kMapScrollBarWidth + 2)); + mapHScroll->SetPosition(Point::Create(0, 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 + 2, 0)); + mapVScroll->SetPosition(Point::Create(mapWindowRect.right - kMapScrollBarWidth + 1, 0)); mapVScroll->Resize(kMapScrollBarWidth, mapWindowRect.bottom - kMapScrollBarWidth + 3); mapTopRoom = mapVScroll->GetState(); @@ -359,8 +359,8 @@ void OpenMapWindow (void) { CreateNailOffscreen(); QSetRect(&mapWindowRect, 0, 0, - mapRoomsWide * kMapRoomWidth + kMapScrollBarWidth - 2, - mapRoomsHigh * kMapRoomHeight + kMapScrollBarWidth - 2); + mapRoomsWide * kMapRoomWidth + kMapScrollBarWidth - 1, + mapRoomsHigh * kMapRoomHeight + kMapScrollBarWidth - 1); const uint16_t windowStyle = PortabilityLayer::WindowStyleFlags::kTitleBar | PortabilityLayer::WindowStyleFlags::kResizable | PortabilityLayer::WindowStyleFlags::kMiniBar | PortabilityLayer::WindowStyleFlags::kCloseBox;; diff --git a/PortabilityLayer/PLControlDefinitions.cpp b/PortabilityLayer/PLControlDefinitions.cpp index e00f673..afde9a5 100644 --- a/PortabilityLayer/PLControlDefinitions.cpp +++ b/PortabilityLayer/PLControlDefinitions.cpp @@ -20,8 +20,12 @@ int FindControl(Point point, WindowPtr window, PortabilityLayer::Widget **outCon const Rect widgetRect = widget->GetRect(); if (widgetRect.Contains(point)) { - *outControl = widget; - return kControlButtonPart; + int part = widget->ResolvePart(point); + if (part != 0) + { + *outControl = widget; + return part; + } } } diff --git a/PortabilityLayer/PLScrollBarWidget.cpp b/PortabilityLayer/PLScrollBarWidget.cpp index fa4e088..af34b76 100644 --- a/PortabilityLayer/PLScrollBarWidget.cpp +++ b/PortabilityLayer/PLScrollBarWidget.cpp @@ -1,14 +1,238 @@ #include "PLScrollBarWidget.h" +#include "PLControlDefinitions.h" +#include "PLStandardColors.h" namespace PortabilityLayer { ScrollBarWidget::ScrollBarWidget(const WidgetBasicState &state) : WidgetSpec(state) + , m_min(0) + , m_max(0) + , m_gripSize(0) + , m_gripPos(0) + , m_laneCapacity(0) { } + WidgetHandleState_t ScrollBarWidget::ProcessEvent(const TimeTaggedVOSEvent &evt) + { + if (!m_visible || !m_enabled) + return WidgetHandleStates::kIgnored; + + return WidgetHandleStates::kIgnored; + } + + void ScrollBarWidget::OnEnabledChanged() + { + DrawControl(m_window->GetDrawSurface()); + } + bool ScrollBarWidget::Init(const WidgetBasicState &state) { + m_min = state.m_min; + m_max = state.m_max; + + RefreshGrip(); + return true; } + + void ScrollBarWidget::DrawControl(DrawSurface *surface) + { + surface->SetForeColor(StdColors::White()); + surface->FillRect(this->m_rect.Inset(1, 1)); + + if (m_rect.Width() < 16 || m_rect.Height() < 16) + return; + + if (IsHorizontal()) + DrawControlHorizontal(surface); + else + DrawControlVertical(surface); + } + + void ScrollBarWidget::DrawControlHorizontal(DrawSurface *surface) + { + surface->SetForeColor(StdColors::Black()); + surface->FrameRect(m_rect); + + const Rect leftArrowRect = Rect::Create(m_rect.top, m_rect.left, m_rect.bottom, m_rect.left + 16); + DrawBeveledBox(surface, leftArrowRect); + + surface->SetForeColor(StdColors::Black()); + for (int i = 0; i < 4; i++) + { + const Rect arrowSegRect = Rect::Create(7 - i + leftArrowRect.top, 6 + i + leftArrowRect.left, 9 + i + leftArrowRect.top, 7 + i + leftArrowRect.left); + surface->FillRect(arrowSegRect); + } + + const Rect rightArrowRect = Rect::Create(m_rect.top, m_rect.right - 16, m_rect.bottom, m_rect.right); + DrawBeveledBox(surface, rightArrowRect); + + surface->SetForeColor(StdColors::Black()); + for (int i = 0; i < 4; i++) + { + const Rect arrowSegRect = Rect::Create(4 + i + rightArrowRect.top, 6 + i + rightArrowRect.left, 12 - i + rightArrowRect.top, 7 + i + rightArrowRect.left); + surface->FillRect(arrowSegRect); + } + + const Rect laneRect = Rect::Create(m_rect.top, leftArrowRect.right, m_rect.bottom, rightArrowRect.left); + + surface->SetForeColor(RGBAColor::Create(136, 136, 136, 255)); + surface->FillRect(Rect::Create(laneRect.top + 1, laneRect.left, laneRect.top + 2, laneRect.right)); + + surface->SetForeColor(RGBAColor::Create(187, 187, 187, 255)); + surface->FillRect(Rect::Create(laneRect.top + 2, laneRect.left, laneRect.bottom - 2, laneRect.right)); + + surface->SetForeColor(StdColors::White()); + surface->FillRect(Rect::Create(laneRect.bottom - 2, laneRect.left, laneRect.bottom - 1, laneRect.right)); + + surface->SetForeColor(StdColors::Black()); + surface->FillRect(Rect::Create(laneRect.top, laneRect.left, laneRect.top + 1, laneRect.right)); + surface->FillRect(Rect::Create(laneRect.bottom - 1, laneRect.left, laneRect.bottom, laneRect.right)); + + + if (m_laneCapacity > 0) + DrawBeveledBox(surface, Rect::Create(laneRect.top, laneRect.left + m_gripPos, laneRect.bottom, laneRect.left + m_gripPos + m_gripSize)); + } + + void ScrollBarWidget::DrawControlVertical(DrawSurface *surface) + { + surface->SetForeColor(StdColors::Black()); + surface->FrameRect(m_rect); + + const Rect topArrowRect = Rect::Create(m_rect.top, m_rect.left, m_rect.top + 16, m_rect.right); + DrawBeveledBox(surface, topArrowRect); + + surface->SetForeColor(StdColors::Black()); + for (int i = 0; i < 4; i++) + { + const Rect arrowSegRect = Rect::Create(6 + i + topArrowRect.top, 7 - i + topArrowRect.left, 7 + i + topArrowRect.top, 9 + i + topArrowRect.left); + surface->FillRect(arrowSegRect); + } + + const Rect bottomArrowRect = Rect::Create(m_rect.bottom - 16, m_rect.left, m_rect.bottom, m_rect.right); + DrawBeveledBox(surface, bottomArrowRect); + + surface->SetForeColor(StdColors::Black()); + for (int i = 0; i < 4; i++) + { + const Rect arrowSegRect = Rect::Create(6 + i + bottomArrowRect.top, 4 + i + bottomArrowRect.left, 7 + i + bottomArrowRect.top, 12 - i + bottomArrowRect.left); + surface->FillRect(arrowSegRect); + } + + const Rect laneRect = Rect::Create(topArrowRect.bottom, m_rect.left, bottomArrowRect.top, m_rect.right); + + surface->SetForeColor(RGBAColor::Create(136, 136, 136, 255)); + surface->FillRect(Rect::Create(laneRect.top, laneRect.left + 1, laneRect.bottom, laneRect.left + 2)); + + surface->SetForeColor(RGBAColor::Create(187, 187, 187, 255)); + surface->FillRect(Rect::Create(laneRect.top, laneRect.left + 2, laneRect.bottom, laneRect.right - 2)); + + surface->SetForeColor(StdColors::White()); + surface->FillRect(Rect::Create(laneRect.bottom, laneRect.right - 2, laneRect.bottom, laneRect.right - 1)); + + surface->SetForeColor(StdColors::Black()); + surface->FillRect(Rect::Create(laneRect.top, laneRect.left, laneRect.bottom, laneRect.left + 1)); + surface->FillRect(Rect::Create(laneRect.top, laneRect.right - 1, laneRect.bottom, laneRect.right)); + + if (m_laneCapacity > 0) + DrawBeveledBox(surface, Rect::Create(laneRect.top + m_gripPos, laneRect.left, laneRect.top + m_gripPos + m_gripSize, laneRect.right)); + } + + void ScrollBarWidget::DrawBeveledBox(DrawSurface *surface, const Rect &rect) + { + surface->SetForeColor(StdColors::Black()); + surface->FrameRect(rect); + + surface->SetForeColor(RGBAColor::Create(187, 187, 187, 187)); + surface->FillRect(rect.Inset(1, 1)); + + surface->SetForeColor(StdColors::White()); + surface->FillRect(Rect::Create(rect.top + 1, rect.left + 1, rect.top + 2, rect.right - 2)); + surface->FillRect(Rect::Create(rect.top + 2, rect.left + 1, rect.bottom - 2, rect.left + 2)); + + surface->SetForeColor(RGBAColor::Create(136, 136, 136, 136)); + surface->FillRect(Rect::Create(rect.bottom - 2, rect.left + 2, rect.bottom - 1, rect.right - 1)); + surface->FillRect(Rect::Create(rect.top + 2, rect.right - 2, rect.bottom - 2, rect.right - 1)); + } + + bool ScrollBarWidget::IsHorizontal() const + { + return m_rect.Width() > m_rect.Height(); + } + + bool ScrollBarWidget::Isvertical() const + { + return !this->IsHorizontal(); + } + + void ScrollBarWidget::RefreshGrip() + { + m_gripSize = 16; + m_laneCapacity = 0; + m_gripPos = 0; + + if (m_gripSize > 0 && m_min < m_max) + { + if (IsHorizontal()) + m_laneCapacity = static_cast(m_rect.Width() - 32) - m_gripSize; + else + m_laneCapacity = static_cast(m_rect.Height() - 32) - m_gripSize; + + if (m_laneCapacity < 0) + m_laneCapacity = 0; + + if (m_laneCapacity > 0) + { + m_gripPos = 0; + if (m_state >= m_max) + m_gripPos = m_laneCapacity; + else if (m_state > m_min) + m_gripPos = (m_state * m_laneCapacity) / (m_max - m_min); + } + else + m_gripPos = 0; + } + } + + void ScrollBarWidget::OnStateChanged() + { + RefreshGrip(); + DrawControl(m_window->GetDrawSurface()); + } + + int ScrollBarWidget::ResolvePart(const Point &point) const + { + if (!m_rect.Contains(point)) + return 0; + + int32_t span = 0; + int32_t coord = 0; + const bool isHorizontal = IsHorizontal(); + if (isHorizontal) + { + span = m_rect.Width(); + coord = point.h - m_rect.left; + } + else + { + span = m_rect.Height(); + coord = point.v - m_rect.top; + } + + if (coord < 16) + return isHorizontal ? kControlDownButtonPart : kControlUpButtonPart; + + if (coord < m_gripPos) + return isHorizontal ? kControlPageDownPart : kControlPageUpPart; + + if (coord - m_gripPos < m_gripSize) + return kControlIndicatorPart; + + if (coord < span - 16) + return isHorizontal ? kControlPageUpPart : kControlPageDownPart; + + return isHorizontal ? kControlUpButtonPart : kControlDownButtonPart; + } } diff --git a/PortabilityLayer/PLScrollBarWidget.h b/PortabilityLayer/PLScrollBarWidget.h index 4ceb563..d10361f 100644 --- a/PortabilityLayer/PLScrollBarWidget.h +++ b/PortabilityLayer/PLScrollBarWidget.h @@ -3,6 +3,8 @@ #include "PascalStr.h" #include "PLWidgets.h" +struct Rect; + namespace PortabilityLayer { class ScrollBarWidget final : public WidgetSpec @@ -11,5 +13,30 @@ namespace PortabilityLayer explicit ScrollBarWidget(const WidgetBasicState &state); bool Init(const WidgetBasicState &state) override; + + void OnEnabledChanged() override; + WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt) override; + void DrawControl(DrawSurface *surface) override; + + void OnStateChanged() override; + + int ResolvePart(const Point &point) const override; + + private: + bool IsHorizontal() const; + bool Isvertical() const; + + void DrawControlHorizontal(DrawSurface *surface); + void DrawControlVertical(DrawSurface *surface); + + void RefreshGrip(); + + static void DrawBeveledBox(DrawSurface *surface, const Rect &rect); + + int32_t m_min; + int32_t m_max; + int32_t m_gripSize; + int32_t m_gripPos; + int32_t m_laneCapacity; }; } diff --git a/PortabilityLayer/PLWidgets.cpp b/PortabilityLayer/PLWidgets.cpp index 96734b8..0ce4a80 100644 --- a/PortabilityLayer/PLWidgets.cpp +++ b/PortabilityLayer/PLWidgets.cpp @@ -1,5 +1,6 @@ #include "PLWidgets.h" #include "MemoryManager.h" +#include "PLControlDefinitions.h" namespace PortabilityLayer { @@ -99,6 +100,11 @@ namespace PortabilityLayer return GetRect(); } + int Widget::ResolvePart(const Point &point) const + { + return kControlButtonPart; + } + void Widget::GainFocus() { } diff --git a/PortabilityLayer/PLWidgets.h b/PortabilityLayer/PLWidgets.h index a6676b1..46e5eb9 100644 --- a/PortabilityLayer/PLWidgets.h +++ b/PortabilityLayer/PLWidgets.h @@ -74,6 +74,8 @@ namespace PortabilityLayer virtual bool HandlesTickEvents() const; virtual Rect GetExpandedRect() const; + virtual int ResolvePart(const Point &point) const; + const Rect &GetRect() const; Window *GetWindow() const;