Files
Aerofoil/PortabilityLayer/PLPopupMenuWidget.cpp

147 lines
4.4 KiB
C++
Raw Normal View History

2020-01-05 02:33:03 -05:00
#include "PLPopupMenuWidget.h"
2020-02-23 20:21:04 -05:00
#include "MenuManager.h"
#include "PLMenus.h"
#include "PLPasStr.h"
2020-05-21 05:01:16 -04:00
#include "PLQDraw.h"
2020-02-23 20:21:04 -05:00
#include "PLStandardColors.h"
2020-03-01 17:01:35 -05:00
#include "PLTimeTaggedVOSEvent.h"
2020-05-21 05:01:16 -04:00
#include "RenderedFont.h"
2020-09-12 14:01:51 -04:00
#include "GpRenderedFontMetrics.h"
2020-05-21 03:30:11 -04:00
#include "ResolveCachingColor.h"
2020-02-23 20:21:04 -05:00
#include "FontFamily.h"
2020-03-01 17:01:35 -05:00
#include "Vec2i.h"
2020-02-23 20:21:04 -05:00
2020-05-18 02:03:17 -04:00
static const int kLightGray = 238;
static const int kMidGray = 221;
static const int kMidDarkGray = 170;
static const int kDarkGray = 102;
2020-01-05 02:33:03 -05:00
namespace PortabilityLayer
{
PopupMenuWidget::PopupMenuWidget(const WidgetBasicState &state)
: WidgetSpec<PopupMenuWidget>(state)
{
}
2020-03-01 17:01:35 -05:00
PopupMenuWidget::~PopupMenuWidget()
{
if (m_menu)
m_menu.Dispose();
}
2020-05-18 02:03:17 -04:00
bool PopupMenuWidget::Init(const WidgetBasicState &state, const void *additionalData)
2020-01-05 02:33:03 -05:00
{
2020-03-01 17:01:35 -05:00
m_menu = ::GetMenu(state.m_resID);
2020-02-23 20:21:04 -05:00
if (!m_menu)
return false;
2020-01-05 02:33:03 -05:00
return true;
}
2020-02-23 20:21:04 -05:00
2020-09-12 22:29:57 -04:00
WidgetHandleState_t PopupMenuWidget::ProcessEvent(void *captureContext, const TimeTaggedVOSEvent &evt)
2020-03-01 17:01:35 -05:00
{
if (evt.IsLMouseDownEvent())
{
const GpMouseInputEvent &mouseEvent = evt.m_vosEvent.m_event.m_mouseInputEvent;
const Vec2i globalPoint = Vec2i(mouseEvent.m_x, mouseEvent.m_y);
2020-05-20 17:20:50 -04:00
const Vec2i localPoint = globalPoint - m_window->GetPosition();
2020-03-01 17:01:35 -05:00
if (this->m_rect.Contains(Point::Create(localPoint.m_x, localPoint.m_y)))
{
2020-09-12 22:29:57 -04:00
int16_t part = Capture(captureContext, Point::Create(localPoint.m_x, localPoint.m_y), nullptr);
2020-03-01 17:01:35 -05:00
if (part >= 1)
return WidgetHandleStates::kActivated;
else
return WidgetHandleStates::kIgnored;
}
}
return WidgetHandleStates::kIgnored;
}
2020-09-12 22:29:57 -04:00
int16_t PopupMenuWidget::Capture(void *captureContext, const Point &pos, WidgetUpdateCallback_t callback)
2020-03-01 17:01:35 -05:00
{
MenuManager *mm = PortabilityLayer::MenuManager::GetInstance();
2020-05-20 17:20:50 -04:00
const Vec2i popupMenuPos = m_window->GetPosition() + Vec2i(m_rect.left, m_rect.top);
const Vec2i globalPos = Vec2i(pos.h, pos.v) + m_window->GetPosition();
2020-03-01 17:01:35 -05:00
uint16_t item = 0;
mm->PopupMenuSelect(m_menu, popupMenuPos, globalPos, m_state - 1, &item);
if (item < 1)
return -1;
this->SetState(item);
return item;
}
2020-02-23 20:21:04 -05:00
void PopupMenuWidget::DrawControl(DrawSurface *surface)
{
2020-05-21 03:30:11 -04:00
PortabilityLayer::ResolveCachingColor whiteColor = StdColors::White();
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
PortabilityLayer::ResolveCachingColor midGrayColor = RGBAColor::Create(kMidGray, kMidGray, kMidGray, 255);
PortabilityLayer::ResolveCachingColor darkGrayColor = RGBAColor::Create(kDarkGray, kDarkGray, kDarkGray, 255);
2020-02-23 20:21:04 -05:00
const Rect rect = m_rect;
const Rect innerRect = rect.Inset(2, 2);
2020-05-21 03:30:11 -04:00
surface->FillRect(rect, blackColor);
2020-05-18 02:03:17 -04:00
2020-05-21 03:30:11 -04:00
surface->FillRect(rect.Inset(1, 1), whiteColor);
2020-05-18 02:03:17 -04:00
2020-05-21 03:30:11 -04:00
surface->FillRect(rect.Inset(2, 2), midGrayColor);
2020-05-18 02:03:17 -04:00
const Rect inset2Rect = rect.Inset(2, 2);
2020-05-21 03:30:11 -04:00
surface->FillRect(Rect::Create(inset2Rect.bottom, inset2Rect.left, inset2Rect.bottom + 1, inset2Rect.right + 1), darkGrayColor);
surface->FillRect(Rect::Create(inset2Rect.top, inset2Rect.right, inset2Rect.bottom + 1, inset2Rect.right + 1), darkGrayColor);
2020-02-23 20:21:04 -05:00
Rect textRect = innerRect;
2020-05-18 03:51:20 -04:00
textRect.right -= 11;
2020-02-23 20:21:04 -05:00
PortabilityLayer::RenderedFont *sysFont = GetFont(FontPresets::kSystem12Bold);
2020-05-21 05:01:16 -04:00
Point basePoint = Point::Create(textRect.left + 2, (textRect.top + textRect.bottom + sysFont->GetMetrics().m_ascent + 1) / 2 - 1);
2020-02-23 20:21:04 -05:00
2020-05-21 05:01:16 -04:00
surface->DrawStringConstrained(basePoint, GetString(), textRect, blackColor, sysFont);
2020-02-23 20:21:04 -05:00
Point arrowMidPoint = Point::Create(textRect.right + 5, (textRect.top + textRect.bottom + 1) / 2);
2020-05-18 03:51:20 -04:00
const Rect arrowRects[4] =
2020-02-23 20:21:04 -05:00
{
2020-05-18 03:51:20 -04:00
Rect::Create(arrowMidPoint.v - 2, arrowMidPoint.h - 3, arrowMidPoint.v - 1, arrowMidPoint.h + 4),
2020-02-23 20:21:04 -05:00
Rect::Create(arrowMidPoint.v - 1, arrowMidPoint.h - 2, arrowMidPoint.v, arrowMidPoint.h + 3),
Rect::Create(arrowMidPoint.v, arrowMidPoint.h - 1, arrowMidPoint.v + 1, arrowMidPoint.h + 2),
Rect::Create(arrowMidPoint.v + 1, arrowMidPoint.h, arrowMidPoint.v + 2, arrowMidPoint.h + 1)
};
2020-05-18 03:51:20 -04:00
for (int i = 0; i < 4; i++)
2020-02-23 20:21:04 -05:00
{
const Rect constrainedRect = innerRect.Intersect(arrowRects[i]);
2020-05-21 03:30:11 -04:00
surface->FillRect(constrainedRect, blackColor);
2020-02-23 20:21:04 -05:00
}
}
2020-03-01 17:01:35 -05:00
void PopupMenuWidget::OnStateChanged()
{
DrawControl(m_window->GetDrawSurface());
}
2020-02-23 20:21:04 -05:00
PLPasStr PopupMenuWidget::GetString() const
{
2020-03-01 17:01:35 -05:00
if (m_state < 1)
return PSTR("");
2020-02-23 20:21:04 -05:00
const Menu *menu = (*m_menu);
return PortabilityLayer::MenuManager::GetInstance()->GetItemText(m_menu, m_state - 1);
}
2020-03-01 17:01:35 -05:00
const THandle<Menu> &PopupMenuWidget::GetMenu() const
{
return m_menu;
}
2020-01-05 02:33:03 -05:00
}