More window chrome improvements

This commit is contained in:
elasota
2020-05-18 02:03:17 -04:00
parent f590613f83
commit ea16d0ffca
41 changed files with 804 additions and 429 deletions

View File

@@ -21,6 +21,7 @@
#include "PLTimeTaggedVOSEvent.h"
#include "PLWidgets.h"
#include "QDPixMap.h"
#include "Rect2i.h"
#include "ResTypeID.h"
#include "SharedTypes.h"
#include "UTF8.h"
@@ -107,6 +108,8 @@ namespace PortabilityLayer
static void MakeStringSubstitutions(uint8_t *outStr, const uint8_t *inStr, const DialogTextSubstitutions *substitutions);
int16_t ExecuteModalInDarkenStack(DialogFilterFunc_t filterFunc);
Window *m_window;
DialogItem *m_items;
size_t m_numItems;
@@ -334,6 +337,19 @@ namespace PortabilityLayer
}
int16_t DialogImpl::ExecuteModal(DialogFilterFunc_t filterFunc)
{
Window *exclWindow = this->GetWindow();
WindowManager::GetInstance()->SwapExclusiveWindow(exclWindow);
int16_t result = ExecuteModalInDarkenStack(filterFunc);
WindowManager::GetInstance()->SwapExclusiveWindow(exclWindow);
return result;
}
int16_t DialogImpl::ExecuteModalInDarkenStack(DialogFilterFunc_t filterFunc)
{
Window *window = this->GetWindow();
Widget *capturingWidget = nullptr;
@@ -367,6 +383,18 @@ namespace PortabilityLayer
}
else
{
if (evt.IsLMouseDownEvent())
{
const GpMouseInputEvent &mouseEvent = evt.m_vosEvent.m_event.m_mouseInputEvent;
Rect2i windowFullRect = WindowManager::GetInstance()->GetWindowFullRect(window);
if (!windowFullRect.Contains(Vec2i(mouseEvent.m_x, mouseEvent.m_y)))
{
PortabilityLayer::HostSystemServices::GetInstance()->Beep();
continue;
}
}
const size_t numItems = this->m_numItems;
for (size_t i = 0; i < numItems; i++)
{
@@ -432,28 +460,40 @@ namespace PortabilityLayer
switch (templateItem.m_serializedType)
{
case SerializedDialogItemTypeCodes::kButton:
widget = ButtonWidget::Create(basicState);
{
ButtonWidget::AdditionalData addlData;
addlData.m_buttonStyle = ButtonWidget::kButtonStyle_Button;
widget = ButtonWidget::Create(basicState, &addlData);
}
break;
case SerializedDialogItemTypeCodes::kLabel:
widget = LabelWidget::Create(basicState);
widget = LabelWidget::Create(basicState, nullptr);
break;
case SerializedDialogItemTypeCodes::kIcon:
widget = IconWidget::Create(basicState);
widget = IconWidget::Create(basicState, nullptr);
break;
case SerializedDialogItemTypeCodes::kImage:
widget = ImageWidget::Create(basicState);
widget = ImageWidget::Create(basicState, nullptr);
break;
case SerializedDialogItemTypeCodes::kCheckBox:
widget = CheckboxWidget::Create(basicState);
{
ButtonWidget::AdditionalData addlData;
addlData.m_buttonStyle = ButtonWidget::kButtonStyle_CheckBox;
widget = ButtonWidget::Create(basicState, &addlData);
}
break;
case SerializedDialogItemTypeCodes::kRadioButton:
widget = RadioButtonWidget::Create(basicState);
{
ButtonWidget::AdditionalData addlData;
addlData.m_buttonStyle = ButtonWidget::kButtonStyle_Radio;
widget = ButtonWidget::Create(basicState, &addlData);
}
break;
case SerializedDialogItemTypeCodes::kEditBox:
widget = EditboxWidget::Create(basicState);
widget = EditboxWidget::Create(basicState, nullptr);
break;
default:
widget = InvisibleWidget::Create(basicState);
widget = InvisibleWidget::Create(basicState, nullptr);
break;
}
@@ -613,9 +653,11 @@ namespace PortabilityLayer
const Rect rect = header.m_rect.ToRect();
const int16_t style = header.m_style;
Dialog *dialog = LoadDialogFromTemplate(header.m_itemsResID, rect, header.m_visible != 0, header.m_hasCloseBox != 0, header.m_referenceConstant, positionSpec, behindWindow, PLPasStr(titlePStr), substitutions);
dlogH.Dispose();
return LoadDialogFromTemplate(header.m_itemsResID, rect, header.m_visible != 0, header.m_hasCloseBox != 0, header.m_referenceConstant, positionSpec, behindWindow, PLPasStr(titlePStr), substitutions);
return dialog;
}
Dialog *DialogManagerImpl::LoadDialogFromTemplate(int16_t templateResID, const Rect &rect, bool visible, bool hasCloseBox, uint32_t referenceConstant, uint16_t positionSpec, Window *behindWindow, const PLPasStr &title, const DialogTextSubstitutions *substitutions)

View File

@@ -963,7 +963,7 @@ namespace PortabilityLayer
const PixMap *pixMap = *m_menuBarGraf->m_port.GetPixMap();
const size_t width = pixMap->m_rect.right - pixMap->m_rect.left;
const size_t height = pixMap->m_rect.bottom - pixMap->m_rect.top;
displayDriver->DrawSurface(m_menuBarGraf->m_ddSurface, 0, 0, width, height);
displayDriver->DrawSurface(m_menuBarGraf->m_ddSurface, 0, 0, width, height, nullptr);
}
}
@@ -988,7 +988,7 @@ namespace PortabilityLayer
yCoordinate = popupPosition.m_y;
}
displayDriver->DrawSurface(renderedMenu->m_ddSurface, xCoordinate, yCoordinate, pixMap->m_rect.right, pixMap->m_rect.bottom);
displayDriver->DrawSurface(renderedMenu->m_ddSurface, xCoordinate, yCoordinate, pixMap->m_rect.right, pixMap->m_rect.bottom, nullptr);
}
}
@@ -1263,6 +1263,18 @@ namespace PortabilityLayer
{
assert(initialItem < menu->numMenuItems);
m_popupPosition.m_y -= static_cast<int32_t>(menu->menuItems[initialItem].layoutYOffset);
if (m_popupPosition.m_y < static_cast<int32_t>(kMenuBarHeight))
m_popupPosition.m_y = kMenuBarHeight;
else
{
int32_t popupBottom = m_popupPosition.m_y + menu->layoutFinalHeight;
unsigned int displayHeight = 0;
PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(nullptr, &displayHeight, nullptr);
if (popupBottom > static_cast<int32_t>(displayHeight))
m_popupPosition.m_y -= popupBottom - static_cast<int32_t>(displayHeight);
}
}
RenderMenu(menu);

View File

@@ -1,139 +1,165 @@
#include "PLButtonWidget.h"
#include "PLCore.h"
#include "PLControlDefinitions.h"
#include "PLRegions.h"
#include "PLTimeTaggedVOSEvent.h"
#include "PLStandardColors.h"
#include "FontFamily.h"
#include "SimpleGraphic.h"
#include <algorithm>
static const int kLightGray = 238;
static const int kMidGray = 221;
static const int kMidDarkGray = 170;
static const int kDarkGray = 102;
#ifdef CLR
#undef CLR
#endif
#define CLR(n) { n, n, n, 255}
static const PortabilityLayer::RGBAColor gs_buttonTopLeftCornerGraphicPixels[] =
{
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { kMidGray, kMidGray, kMidGray, 255 },
{ 0, 0, 0, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { 255, 255, 255, 255 }
CLR(0), CLR(0), CLR(0),
CLR(0), CLR(0), CLR(kMidGray),
CLR(0), CLR(kMidGray), CLR(255)
};
static const PortabilityLayer::RGBAColor gs_buttonTopRightCornerGraphicPixels[] =
{
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ kMidGray, kMidGray, kMidGray, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ 255, 255, 255, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { 0, 0, 0, 255 }
CLR(0), CLR(0), CLR(0),
CLR(kMidGray), CLR(0), CLR(0),
CLR(255), CLR(kMidGray), CLR(0)
};
static const PortabilityLayer::RGBAColor gs_buttonBottomLeftCornerGraphicPixels[] =
{
{ 0, 0, 0, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { 255, 255, 255, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { kMidGray, kMidGray, kMidGray, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }
CLR(0), CLR(kMidGray), CLR(255),
CLR(0), CLR(0), CLR(kMidGray),
CLR(0), CLR(0), CLR(0)
};
static const PortabilityLayer::RGBAColor gs_buttonBottomRightCornerGraphicPixels[] =
{
{ kMidGray, kMidGray, kMidGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { 0, 0, 0, 255 },
{ kDarkGray, kDarkGray, kDarkGray, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }
CLR(kMidGray), CLR(kDarkGray), CLR(0),
CLR(kDarkGray), CLR(0), CLR(0),
CLR(0), CLR(0), CLR(0)
};
// Pressed
static const PortabilityLayer::RGBAColor gs_buttonPressedTopLeftCornerGraphicPixels[] =
{
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 },
{ 0, 0, 0, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }
CLR(0), CLR(0), CLR(0),
CLR(0), CLR(0), CLR(kDarkGray),
CLR(0), CLR(kDarkGray), CLR(kDarkGray)
};
static const PortabilityLayer::RGBAColor gs_buttonPressedTopRightCornerGraphicPixels[] =
{
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ kDarkGray, kDarkGray, kDarkGray, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { 0, 0, 0, 255 }
CLR(0), CLR(0), CLR(0),
CLR(kDarkGray), CLR(0), CLR(0),
CLR(kDarkGray), CLR(kDarkGray), CLR(0)
};
static const PortabilityLayer::RGBAColor gs_buttonPressedBottomLeftCornerGraphicPixels[] =
{
{ 0, 0, 0, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }
CLR(0), CLR(kDarkGray), CLR(kDarkGray),
CLR(0), CLR(0), CLR(kDarkGray),
CLR(0), CLR(0), CLR(0)
};
static const PortabilityLayer::RGBAColor gs_buttonPressedBottomRightCornerGraphicPixels[] =
{
{ kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { 0, 0, 0, 255 },
{ kDarkGray, kDarkGray, kDarkGray, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }
CLR(kDarkGray), CLR(kDarkGray), CLR(0),
CLR(kDarkGray), CLR(0), CLR(0),
CLR(0), CLR(0), CLR(0)
};
// Disabled
static const PortabilityLayer::RGBAColor gs_buttonDisabledTopLeftCornerGraphicPixels[] =
{
{ kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 },
{ kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { kLightGray, kLightGray, kLightGray, 255 },
{ kDarkGray, kDarkGray, kDarkGray, 255 }, { kLightGray, kLightGray, kLightGray, 255 }, { kLightGray, kLightGray, kLightGray, 255 }
CLR(kDarkGray), CLR(kDarkGray), CLR(kDarkGray),
CLR(kDarkGray), CLR(kDarkGray), CLR(kLightGray),
CLR(kDarkGray), CLR(kLightGray), CLR(kLightGray)
};
static const PortabilityLayer::RGBAColor gs_buttonDisabledTopRightCornerGraphicPixels[] =
{
{ kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 },
{ kLightGray, kLightGray, kLightGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 },
{ kLightGray, kLightGray, kLightGray, 255 }, { kLightGray, kLightGray, kLightGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }
CLR(kDarkGray), CLR(kDarkGray), CLR(kDarkGray),
CLR(kLightGray), CLR(kDarkGray), CLR(kDarkGray),
CLR(kLightGray), CLR(kLightGray), CLR(kDarkGray)
};
static const PortabilityLayer::RGBAColor gs_buttonDisabledBottomLeftCornerGraphicPixels[] =
{
{ kDarkGray, kDarkGray, kDarkGray, 255 }, { kLightGray, kLightGray, kLightGray, 255 }, { kLightGray, kLightGray, kLightGray, 255 },
{ kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { kLightGray, kLightGray, kLightGray, 255 },
{ kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }
CLR(kDarkGray), CLR(kLightGray), CLR(kLightGray),
CLR(kDarkGray), CLR(kDarkGray), CLR(kLightGray),
CLR(kDarkGray), CLR(kDarkGray), CLR(kDarkGray)
};
static const PortabilityLayer::RGBAColor gs_buttonDisabledBottomRightCornerGraphicPixels[] =
{
{ kLightGray, kLightGray, kLightGray, 255 }, { kLightGray, kLightGray, kLightGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 },
{ kLightGray, kLightGray, kLightGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 },
{ kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }
CLR(kLightGray), CLR(kLightGray), CLR(kDarkGray),
CLR(kLightGray), CLR(kDarkGray), CLR(kDarkGray),
CLR(kDarkGray), CLR(kDarkGray), CLR(kDarkGray)
};
// Default boundary
static const PortabilityLayer::RGBAColor gs_buttonDefaultTopLeftCornerGraphicPixels[] =
{
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 255, 255, 255, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 255, 255, 255, 255 }, { kMidGray, kMidGray, kMidGray, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 255, 255, 255, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 },
{ 0, 0, 0, 255 }, { 255, 255, 255, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { 0, 0, 0, 255 },
CLR(0), CLR(0), CLR(0), CLR(0), CLR(0),
CLR(0), CLR(0), CLR(0), CLR(0), CLR(255),
CLR(0), CLR(0), CLR(0), CLR(255), CLR(kMidGray),
CLR(0), CLR(0), CLR(255), CLR(kMidGray), CLR(kMidGray),
CLR(0), CLR(255), CLR(kMidGray), CLR(kMidGray), CLR(0),
};
static const PortabilityLayer::RGBAColor gs_buttonDefaultTopRightCornerGraphicPixels[] =
{
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ 255, 255, 255, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ 0, 0, 0, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { 0, 0, 0, 255 },
CLR(0), CLR(0), CLR(0), CLR(0), CLR(0),
CLR(255), CLR(0), CLR(0), CLR(0), CLR(0),
CLR(kMidGray), CLR(kMidGray), CLR(0), CLR(0), CLR(0),
CLR(kMidGray), CLR(kMidGray), CLR(kMidGray), CLR(0), CLR(0),
CLR(0), CLR(kMidGray), CLR(kMidGray), CLR(kDarkGray), CLR(0),
};
static const PortabilityLayer::RGBAColor gs_buttonDefaultBottomLeftCornerGraphicPixels[] =
{
{ 0, 0, 0, 255 }, { 255, 255, 255, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { 0, 0, 0, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
CLR(0), CLR(255), CLR(kMidGray), CLR(kMidGray), CLR(0),
CLR(0), CLR(0), CLR(kMidGray), CLR(kMidGray), CLR(kMidGray),
CLR(0), CLR(0), CLR(0), CLR(kMidGray), CLR(kMidGray),
CLR(0), CLR(0), CLR(0), CLR(0), CLR(kDarkGray),
CLR(0), CLR(0), CLR(0), CLR(0), CLR(0),
};
static const PortabilityLayer::RGBAColor gs_buttonDefaultBottomRightCornerGraphicPixels[] =
{
{ 0, 0, 0, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { 0, 0, 0, 255 },
{ kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ kMidGray, kMidGray, kMidGray, 255 }, { kDarkGray, kDarkGray, kDarkGray, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ kDarkGray, kDarkGray, kDarkGray, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
CLR(0), CLR(kMidGray), CLR(kMidGray), CLR(kDarkGray), CLR(0),
CLR(kMidGray), CLR(kMidGray), CLR(kDarkGray), CLR(0), CLR(0),
CLR(kMidGray), CLR(kDarkGray), CLR(0), CLR(0), CLR(0),
CLR(kDarkGray), CLR(0), CLR(0), CLR(0), CLR(0),
CLR(0), CLR(0), CLR(0), CLR(0), CLR(0),
};
static const PortabilityLayer::RGBAColor gs_buttonRadioGraphicPixels[] =
{
CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),
CLR(0),CLR(0),CLR(0),CLR(255),CLR(255),CLR(255),CLR(255),CLR(255),CLR(255),CLR(0),CLR(0),CLR(0),
CLR(0),CLR(0),CLR(255),CLR(255),CLR(kLightGray),CLR(kLightGray),CLR(kLightGray),CLR(kLightGray),CLR(kMidGray),CLR(kMidGray),CLR(0),CLR(0),
CLR(0),CLR(255),CLR(255),CLR(kLightGray),CLR(kLightGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kDarkGray),CLR(0),
CLR(0),CLR(255),CLR(kLightGray),CLR(kLightGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidDarkGray),CLR(kDarkGray),CLR(0),
CLR(0),CLR(255),CLR(kLightGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidDarkGray),CLR(kDarkGray),CLR(0),
CLR(0),CLR(255),CLR(kLightGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidDarkGray),CLR(kDarkGray),CLR(0),
CLR(0),CLR(255),CLR(kLightGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidDarkGray),CLR(kMidDarkGray),CLR(kDarkGray),CLR(0),
CLR(0),CLR(255),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidGray),CLR(kMidDarkGray),CLR(kMidDarkGray),CLR(kDarkGray),CLR(kDarkGray),CLR(0),
CLR(0),CLR(0),CLR(kMidGray),CLR(kMidGray),CLR(kMidDarkGray),CLR(kMidDarkGray),CLR(kMidDarkGray),CLR(kMidDarkGray),CLR(kDarkGray),CLR(kDarkGray),CLR(0),CLR(0),
CLR(0),CLR(0),CLR(0),CLR(kDarkGray),CLR(kDarkGray),CLR(kDarkGray),CLR(kDarkGray),CLR(kDarkGray),CLR(kDarkGray),CLR(0),CLR(0),CLR(0),
CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),CLR(0),
};
@@ -179,13 +205,23 @@ static const uint8_t gs_buttonDefaultTopRightGraphicMask[] = { 0x86, 0x39, 0xEF,
static const uint8_t gs_buttonDefaultBottomLeftGraphicMask[] = { 0xFB, 0xCE, 0x30, 0xFF };
static const uint8_t gs_buttonDefaultBottomRightGraphicMask[] = { 0xFF, 0xB9, 0x88, 0x7F };
static const uint8_t gs_buttonRadioGraphicMask[] = { 0x1f, 0x83, 0xFC, 0x7F, 0xEF, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xF7, 0xFE, 0x3F, 0xC1, 0xF8 };
static PortabilityLayer::SimpleGraphicInstanceRGBA<12, 12> gs_buttonRadioGraphic(gs_buttonRadioGraphicPixels);
namespace PortabilityLayer
{
ButtonWidget::AdditionalData::AdditionalData()
: m_buttonStyle(kButtonStyle_Button)
{
}
ButtonWidget::ButtonWidget(const WidgetBasicState &state)
: WidgetSpec<ButtonWidget>(state)
, m_text(state.m_text)
, m_haveHighlightOverride(false)
, m_buttonStyle(kButtonStyle_Button)
{
}
@@ -214,7 +250,14 @@ namespace PortabilityLayer
void ButtonWidget::OnEnabledChanged()
{
DrawControl(m_window->GetDrawSurface());
if (m_window)
DrawControl(m_window->GetDrawSurface());
}
void ButtonWidget::OnStateChanged()
{
if (m_window)
DrawControl(m_window->GetDrawSurface());
}
int16_t ButtonWidget::Capture(const Point &pos, WidgetUpdateCallback_t callback)
@@ -254,9 +297,12 @@ namespace PortabilityLayer
}
}
bool ButtonWidget::Init(const WidgetBasicState &state)
bool ButtonWidget::Init(const WidgetBasicState &state, const void *additionalDataPtr)
{
(void)state;
const AdditionalData &additionalData = *static_cast<const AdditionalData *>(additionalDataPtr);
m_buttonStyle = additionalData.m_buttonStyle;
return true;
}
@@ -265,7 +311,36 @@ namespace PortabilityLayer
DrawControlInternal(surface, false);
}
void ButtonWidget::SetString(const PLPasStr &str)
{
m_text = PascalStr<255>(str);
}
PLPasStr ButtonWidget::GetString() const
{
return m_text.ToShortStr();
}
void ButtonWidget::DrawControlInternal(DrawSurface *surface, bool inverted)
{
switch (m_buttonStyle)
{
case kButtonStyle_Button:
DrawAsButton(surface, inverted);
break;
case kButtonStyle_CheckBox:
DrawAsCheck(surface, inverted);
break;
case kButtonStyle_Radio:
DrawAsRadio(surface, inverted);
break;
default:
break;
}
}
void ButtonWidget::DrawAsButton(DrawSurface *surface, bool inverted)
{
const Rect rect = m_rect;
@@ -370,6 +445,163 @@ namespace PortabilityLayer
surface->DrawString(Point::Create(x, y), m_text.ToShortStr(), true);
}
void ButtonWidget::DrawAsCheck(DrawSurface *surface, bool inverted)
{
if (!m_rect.IsValid())
return;
surface->SetForeColor(StdColors::White());
surface->FillRect(m_rect);
uint16_t checkFrameSize = std::min<uint16_t>(12, std::min(m_rect.Width(), m_rect.Height()));
int16_t top = (m_rect.top + m_rect.bottom - static_cast<int16_t>(checkFrameSize)) / 2;
const Rect checkRect = Rect::Create(top, m_rect.left, top + static_cast<int16_t>(checkFrameSize), m_rect.left + static_cast<int16_t>(checkFrameSize));
RGBAColor checkColor;
RGBAColor checkEraseColor;
RGBAColor textColor;
if (!m_enabled)
{
surface->SetForeColor(RGBAColor::Create(kMidGray, kMidGray, kMidGray, 255));
surface->FillRect(checkRect);
surface->SetForeColor(RGBAColor::Create(kLightGray, kLightGray, kLightGray, 255));
surface->FillRect(checkRect.Inset(1, 1));
checkColor = RGBAColor::Create(kMidGray, kMidGray, kMidGray, 255);
checkEraseColor = RGBAColor::Create(kLightGray, kLightGray, kLightGray, 255);
textColor = RGBAColor::Create(kMidGray, kMidGray, kMidGray, 255);
}
else if (inverted)
{
surface->SetForeColor(StdColors::Black());
surface->FillRect(checkRect);
surface->SetForeColor(RGBAColor::Create(kDarkGray, kDarkGray, kDarkGray, 255));
surface->FillRect(checkRect.Inset(1, 1));
checkColor = StdColors::White();
checkEraseColor = RGBAColor::Create(kDarkGray, kDarkGray, kDarkGray, 255);
textColor = StdColors::Black();
}
else
{
surface->SetForeColor(StdColors::Black());
surface->FillRect(checkRect);
surface->SetForeColor(RGBAColor::Create(kMidGray, kMidGray, kMidGray, 255));
surface->FillRect(checkRect.Inset(1, 1));
surface->SetForeColor(RGBAColor::Create(kDarkGray, kDarkGray, kDarkGray, 255));
surface->FillRect(Rect::Create(checkRect.top + 2, checkRect.right - 2, checkRect.bottom - 2, checkRect.right - 1));
surface->FillRect(Rect::Create(checkRect.bottom - 2, checkRect.left + 2, checkRect.bottom - 1, checkRect.right - 1));
surface->SetForeColor(StdColors::White());
surface->FillRect(Rect::Create(checkRect.top + 1, checkRect.left + 1, checkRect.top + 2, checkRect.right - 2));
surface->FillRect(Rect::Create(checkRect.top + 2, checkRect.left + 1, checkRect.bottom - 2, checkRect.left + 2));
checkColor = StdColors::Black();
checkEraseColor = RGBAColor::Create(kMidGray, kMidGray, kMidGray, 255);
textColor = StdColors::Black();
}
if (m_state)
{
const Rect checkmarkRect = checkRect.Inset(3, 3);
if (checkmarkRect.IsValid())
{
surface->SetForeColor(checkColor);
surface->FillRect(checkmarkRect);
if (checkmarkRect.Width() >= 5)
{
int32_t eraseSpan = checkmarkRect.Width() - 4;
int16_t coordinateOffset = 0;
surface->SetForeColor(checkEraseColor);
while (eraseSpan > 0)
{
surface->FillRect(Rect::Create(checkmarkRect.top + coordinateOffset, checkmarkRect.left + 2 + coordinateOffset, checkmarkRect.top + 1 + coordinateOffset, checkmarkRect.right - 2 - coordinateOffset));
surface->FillRect(Rect::Create(checkmarkRect.top + 2 + coordinateOffset, checkmarkRect.left + coordinateOffset, checkmarkRect.bottom - 2 - coordinateOffset, checkmarkRect.left + 1 + coordinateOffset));
surface->FillRect(Rect::Create(checkmarkRect.bottom - 1 - coordinateOffset, checkmarkRect.left + 2 + coordinateOffset, checkmarkRect.bottom - coordinateOffset, checkmarkRect.right - 2 - coordinateOffset));
surface->FillRect(Rect::Create(checkmarkRect.top + 2 + coordinateOffset, checkmarkRect.right - 1 - coordinateOffset, checkmarkRect.bottom - 2 - coordinateOffset, checkmarkRect.right - coordinateOffset));
eraseSpan -= 2;
coordinateOffset++;
}
}
}
}
surface->SetForeColor(textColor);
surface->SetSystemFont(12, FontFamilyFlag_Bold);
int32_t textV = (m_rect.top + m_rect.bottom + surface->MeasureFontAscender()) / 2;
surface->DrawString(Point::Create(m_rect.left + checkFrameSize + 2, textV), m_text.ToShortStr(), true);
}
void ButtonWidget::DrawAsRadio(DrawSurface *surface, bool inverted)
{
if (!m_rect.IsValid())
return;
surface->SetForeColor(StdColors::White());
surface->FillRect(m_rect);
uint16_t checkFrameSize = std::min<uint16_t>(12, std::min(m_rect.Width(), m_rect.Height()));
int16_t top = (m_rect.top + m_rect.bottom - static_cast<int16_t>(checkFrameSize)) / 2;
const Rect checkRect = Rect::Create(top, m_rect.left, top + static_cast<int16_t>(checkFrameSize), m_rect.left + static_cast<int16_t>(checkFrameSize));
RGBAColor radioColor;
RGBAColor textColor;
if (!m_enabled)
{
surface->SetForeColor(RGBAColor::Create(kMidGray, kMidGray, kMidGray, 255));
surface->FillEllipse(checkRect);
surface->SetForeColor(RGBAColor::Create(kLightGray, kLightGray, kLightGray, 255));
surface->FillEllipse(checkRect.Inset(1, 1));
radioColor = RGBAColor::Create(kMidGray, kMidGray, kMidGray, 255);
textColor = RGBAColor::Create(kMidGray, kMidGray, kMidGray, 255);
}
else if (inverted)
{
surface->SetForeColor(StdColors::Black());
surface->FillEllipse(checkRect);
surface->SetForeColor(RGBAColor::Create(kDarkGray, kDarkGray, kDarkGray, 255));
surface->FillEllipse(checkRect.Inset(1, 1));
radioColor = StdColors::Black();
textColor = StdColors::Black();
}
else
{
gs_buttonRadioGraphic.DrawToPixMapWithMask(surface->m_port.GetPixMap(), gs_buttonRadioGraphicMask, checkRect.left, checkRect.top);
radioColor = StdColors::Black();
textColor = StdColors::Black();
}
if (m_state)
{
const Rect checkmarkRect = checkRect.Inset(3, 3);
if (checkmarkRect.IsValid())
{
surface->SetForeColor(radioColor);
surface->FillEllipse(checkmarkRect);
}
}
surface->SetForeColor(textColor);
surface->SetSystemFont(12, FontFamilyFlag_Bold);
int32_t textV = (m_rect.top + m_rect.bottom + surface->MeasureFontAscender()) / 2;
surface->DrawString(Point::Create(m_rect.left + checkFrameSize + 2, textV), m_text.ToShortStr(), true);
}
void ButtonWidget::DrawDefaultButtonChrome(const Rect &rectRef, DrawSurface *surface)
{
const Rect rect = rectRef;

View File

@@ -8,18 +8,32 @@ namespace PortabilityLayer
class ButtonWidget final : public WidgetSpec<ButtonWidget>
{
public:
enum ButtonStyle
{
kButtonStyle_Button,
kButtonStyle_CheckBox,
kButtonStyle_Radio,
};
struct AdditionalData
{
AdditionalData();
ButtonStyle m_buttonStyle;
};
explicit ButtonWidget(const WidgetBasicState &state);
bool Init(const WidgetBasicState &state) override;
bool Init(const WidgetBasicState &state, const void *additionalData) override;
void DrawControl(DrawSurface *surface) override;
void SetString(const PLPasStr &str) override;
PLPasStr GetString() const override;
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt) override;
void OnEnabledChanged() override;
void OnStateChanged() override;
int16_t Capture(const Point &pos, WidgetUpdateCallback_t callback) override;
void SetHighlightStyle(int16_t style, bool enabled) override;
static void DrawDefaultButtonChrome(const Rect &rect, DrawSurface *surface);
@@ -27,7 +41,12 @@ namespace PortabilityLayer
private:
void DrawControlInternal(DrawSurface *surface, bool inverted);
void DrawAsButton(DrawSurface *surface, bool inverted);
void DrawAsRadio(DrawSurface *surface, bool inverted);
void DrawAsCheck(DrawSurface *surface, bool inverted);
PascalStr<255> m_text;
ButtonStyle m_buttonStyle;
bool m_haveHighlightOverride;
};
}

View File

@@ -1,113 +0,0 @@
#include "PLCheckboxWidget.h"
#include "PLStandardColors.h"
#include "FontFamily.h"
#include "PLTimeTaggedVOSEvent.h"
#include <algorithm>
namespace PortabilityLayer
{
CheckboxWidget::CheckboxWidget(const WidgetBasicState &state)
: WidgetSpec<CheckboxWidget>(state)
, m_text(state.m_text)
, m_haveMouseDown(false)
{
}
CheckboxWidget::~CheckboxWidget()
{
}
bool CheckboxWidget::Init(const WidgetBasicState &state)
{
(void)state;
return true;
}
void CheckboxWidget::DrawControl(DrawSurface *surface)
{
if (!m_rect.IsValid())
return;
surface->SetForeColor(StdColors::White());
surface->FillRect(m_rect);
uint16_t checkFrameSize = std::min<uint16_t>(12, std::min(m_rect.Width(), m_rect.Height()));
int16_t top = (m_rect.top + m_rect.bottom - static_cast<int16_t>(checkFrameSize)) / 2;
surface->SetForeColor(StdColors::Black());
const Rect checkRect = Rect::Create(top, m_rect.left, top + static_cast<int16_t>(checkFrameSize), m_rect.left + static_cast<int16_t>(checkFrameSize));
surface->FillRect(checkRect);
surface->SetForeColor(StdColors::White());
surface->FillRect(checkRect.Inset(1, 1));
if (m_state)
{
surface->SetForeColor(StdColors::Black());
surface->DrawLine(Point::Create(checkRect.left + 1, checkRect.top + 1), Point::Create(checkRect.right - 2, checkRect.bottom - 2));
surface->DrawLine(Point::Create(checkRect.right - 2, checkRect.top + 1), Point::Create(checkRect.left + 1, checkRect.bottom - 2));
}
surface->SetForeColor(StdColors::Black());
surface->SetSystemFont(12, FontFamilyFlag_Bold);
int32_t textV = (m_rect.top + m_rect.bottom + surface->MeasureFontAscender()) / 2;
surface->DrawString(Point::Create(m_rect.left + checkFrameSize + 2, textV), m_text.ToShortStr(), true);
}
void CheckboxWidget::SetString(const PLPasStr &str)
{
m_text = PascalStr<255>(str);
}
PLPasStr CheckboxWidget::GetString() const
{
return m_text.ToShortStr();
}
void CheckboxWidget::OnStateChanged()
{
if (m_window)
DrawControl(&m_window->m_surface);
}
WidgetHandleState_t CheckboxWidget::ProcessEvent(const TimeTaggedVOSEvent &evt)
{
if (!m_visible || !m_enabled)
return WidgetHandleStates::kIgnored;
if (m_haveMouseDown)
{
if (evt.IsLMouseUpEvent())
{
m_haveMouseDown = false;
const Point pt = m_window->MouseToLocal(evt.m_vosEvent.m_event.m_mouseInputEvent);
if (m_rect.Contains(pt))
return WidgetHandleStates::kActivated;
else
return WidgetHandleStates::kIgnored;
}
return WidgetHandleStates::kCaptured;
}
else
{
if (evt.IsLMouseDownEvent())
{
const Point pt = m_window->MouseToLocal(evt.m_vosEvent.m_event.m_mouseInputEvent);
if (m_rect.Contains(pt))
{
m_haveMouseDown = true;
return WidgetHandleStates::kCaptured;
}
else
return WidgetHandleStates::kIgnored;
}
}
return WidgetHandleStates::kIgnored;
}
}

View File

@@ -11,17 +11,21 @@ namespace PortabilityLayer
CheckboxWidget(const WidgetBasicState &state);
~CheckboxWidget();
bool Init(const WidgetBasicState &state) override;
bool Init(const WidgetBasicState &state, const void *additionalData) override;
void DrawControl(DrawSurface *surface) override;
void SetString(const PLPasStr &str) override;
PLPasStr GetString() const override;
void OnStateChanged() override;
void OnEnabledChanged() override;
int16_t Capture(const Point &pos, WidgetUpdateCallback_t callback) override;
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt);
private:
void DrawControlInternal(DrawSurface *surface, bool inverted);
PascalStr<255> m_text;
bool m_haveMouseDown;
};

View File

@@ -199,22 +199,6 @@ typedef WindowPtr WindowRef; // wtf?
struct KeyDownStates;
namespace RegionIDs
{
enum RegionID
{
kNone,
kMenuBar = 1,
kContent,
kTitleBar,
kClose,
kResize,
};
}
typedef RegionIDs::RegionID RegionID_t;
static const int everyEvent = -1;
static const int iBeamCursor = 1;

View File

@@ -42,7 +42,7 @@ namespace PortabilityLayer
mm->Release(m_chars);
}
bool EditboxWidget::Init(const WidgetBasicState &state)
bool EditboxWidget::Init(const WidgetBasicState &state, const void *additionalData)
{
PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance();
m_capacity = 255;

View File

@@ -14,7 +14,7 @@ namespace PortabilityLayer
EditboxWidget(const WidgetBasicState &state);
~EditboxWidget();
bool Init(const WidgetBasicState &state) override;
bool Init(const WidgetBasicState &state, const void *additionalData) override;
void DrawControl(DrawSurface *surface) override;
void SetString(const PLPasStr &str) override;

View File

@@ -21,7 +21,7 @@ namespace PortabilityLayer
PixMapImpl::Destroy(m_iconMask);
}
bool IconWidget::Init(const WidgetBasicState &state)
bool IconWidget::Init(const WidgetBasicState &state, const void *additionalData)
{
PL_DEAD(str);

View File

@@ -13,7 +13,7 @@ namespace PortabilityLayer
IconWidget(const WidgetBasicState &state);
~IconWidget() override;
bool Init(const WidgetBasicState &state) override;
bool Init(const WidgetBasicState &state, const void *additionalData) override;
void DrawControl(DrawSurface *surface) override;

View File

@@ -13,7 +13,7 @@ namespace PortabilityLayer
{
}
bool ImageWidget::Init(const WidgetBasicState &state)
bool ImageWidget::Init(const WidgetBasicState &state, const void *additionalData)
{
m_pict = PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('PICT', state.m_resID).StaticCast<BitmapImage>();

View File

@@ -13,7 +13,7 @@ namespace PortabilityLayer
ImageWidget(const WidgetBasicState &state);
~ImageWidget();
bool Init(const WidgetBasicState &state) override;
bool Init(const WidgetBasicState &state, const void *additionalData) override;
void DrawControl(DrawSurface *surface) override;
private:

View File

@@ -14,7 +14,7 @@ namespace PortabilityLayer
{
}
bool InvisibleWidget::Init(const WidgetBasicState &state)
bool InvisibleWidget::Init(const WidgetBasicState &state, const void *additionalData)
{
(void)state;

View File

@@ -10,7 +10,7 @@ namespace PortabilityLayer
explicit InvisibleWidget(const WidgetBasicState &state);
~InvisibleWidget();
bool Init(const WidgetBasicState &state) override;
bool Init(const WidgetBasicState &state, const void *additionalData) override;
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt) override;

View File

@@ -13,7 +13,7 @@ namespace PortabilityLayer
{
}
bool LabelWidget::Init(const WidgetBasicState &state)
bool LabelWidget::Init(const WidgetBasicState &state, const void *additionalData)
{
(void)state;
return true;

View File

@@ -10,7 +10,7 @@ namespace PortabilityLayer
public:
LabelWidget(const WidgetBasicState &state);
bool Init(const WidgetBasicState &state) override;
bool Init(const WidgetBasicState &state, const void *additionalData) override;
void SetString(const PLPasStr &str) override;
PLPasStr GetString() const override;

View File

@@ -8,6 +8,11 @@
#include "FontFamily.h"
#include "Vec2i.h"
static const int kLightGray = 238;
static const int kMidGray = 221;
static const int kMidDarkGray = 170;
static const int kDarkGray = 102;
namespace PortabilityLayer
{
PopupMenuWidget::PopupMenuWidget(const WidgetBasicState &state)
@@ -21,7 +26,7 @@ namespace PortabilityLayer
m_menu.Dispose();
}
bool PopupMenuWidget::Init(const WidgetBasicState &state)
bool PopupMenuWidget::Init(const WidgetBasicState &state, const void *additionalData)
{
m_menu = ::GetMenu(state.m_resID);
if (!m_menu)
@@ -73,18 +78,29 @@ namespace PortabilityLayer
const Rect rect = m_rect;
const Rect innerRect = rect.Inset(2, 2);
surface->SetForeColor(StdColors::White());
surface->FillRect(m_rect.Inset(1, 1));
surface->SetForeColor(StdColors::Black());
surface->FrameRect(m_rect);
surface->FillRect(rect);
surface->SetForeColor(StdColors::White());
surface->FillRect(rect.Inset(1, 1));
surface->SetForeColor(RGBAColor::Create(kMidGray, kMidGray, kMidGray, 255));
surface->FillRect(rect.Inset(2, 2));
const Rect inset2Rect = rect.Inset(2, 2);
surface->SetForeColor(RGBAColor::Create(kDarkGray, kDarkGray, kDarkGray, 255));
surface->FillRect(Rect::Create(inset2Rect.bottom, inset2Rect.left, inset2Rect.bottom + 1, inset2Rect.right + 1));
surface->FillRect(Rect::Create(inset2Rect.top, inset2Rect.right, inset2Rect.bottom + 1, inset2Rect.right + 1));
Rect textRect = innerRect;
textRect.right -= 9;
surface->SetSystemFont(12, PortabilityLayer::FontFamilyFlag_Bold);
Point basePoint = Point::Create(textRect.left + 2, (textRect.top + textRect.bottom + surface->MeasureFontAscender() + 1) / 2);
Point basePoint = Point::Create(textRect.left + 2, (textRect.top + textRect.bottom + surface->MeasureFontAscender() + 1) / 2 - 1);
surface->SetForeColor(StdColors::Black());
surface->DrawStringConstrained(basePoint, GetString(), true, textRect);
Point arrowMidPoint = Point::Create(textRect.right + 5, (textRect.top + textRect.bottom + 1) / 2);

View File

@@ -12,7 +12,7 @@ namespace PortabilityLayer
public:
explicit PopupMenuWidget(const WidgetBasicState &state);
bool Init(const WidgetBasicState &state) override;
bool Init(const WidgetBasicState &state, const void *additionalData) override;
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt);
int16_t Capture(const Point &pos, WidgetUpdateCallback_t callback);

View File

@@ -1,112 +0,0 @@
#include "PLRadioButtonWidget.h"
#include "PLStandardColors.h"
#include "FontFamily.h"
#include "PLTimeTaggedVOSEvent.h"
#include <algorithm>
namespace PortabilityLayer
{
RadioButtonWidget::RadioButtonWidget(const WidgetBasicState &state)
: WidgetSpec<RadioButtonWidget>(state)
, m_text(state.m_text)
, m_haveMouseDown(false)
{
}
RadioButtonWidget::~RadioButtonWidget()
{
}
bool RadioButtonWidget::Init(const WidgetBasicState &state)
{
(void)state;
return true;
}
void RadioButtonWidget::DrawControl(DrawSurface *surface)
{
if (!m_rect.IsValid())
return;
surface->SetForeColor(StdColors::White());
surface->FillRect(m_rect);
uint16_t radioFrameSize = std::min<uint16_t>(12, std::min(m_rect.Width(), m_rect.Height()));
int16_t top = (m_rect.top + m_rect.bottom - static_cast<int16_t>(radioFrameSize)) / 2;
surface->SetForeColor(StdColors::Black());
const Rect radioRect = Rect::Create(top, m_rect.left, top + static_cast<int16_t>(radioFrameSize), m_rect.left + static_cast<int16_t>(radioFrameSize));
surface->FillEllipse(radioRect);
surface->SetForeColor(StdColors::White());
surface->FillEllipse(radioRect.Inset(1, 1));
if (m_state)
{
surface->SetForeColor(StdColors::Black());
surface->FillEllipse(radioRect.Inset(3, 3));
}
surface->SetForeColor(StdColors::Black());
surface->SetSystemFont(12, FontFamilyFlag_Bold);
int32_t textV = (m_rect.top + m_rect.bottom + surface->MeasureFontAscender()) / 2;
surface->DrawString(Point::Create(m_rect.left + radioFrameSize + 2, textV), m_text.ToShortStr(), true);
}
void RadioButtonWidget::SetString(const PLPasStr &str)
{
m_text = PascalStr<255>(str);
}
PLPasStr RadioButtonWidget::GetString() const
{
return m_text.ToShortStr();
}
void RadioButtonWidget::OnStateChanged()
{
if (m_window)
DrawControl(&m_window->m_surface);
}
WidgetHandleState_t RadioButtonWidget::ProcessEvent(const TimeTaggedVOSEvent &evt)
{
if (!m_visible || !m_enabled)
return WidgetHandleStates::kIgnored;
if (m_haveMouseDown)
{
if (evt.IsLMouseUpEvent())
{
m_haveMouseDown = false;
const Point pt = m_window->MouseToLocal(evt.m_vosEvent.m_event.m_mouseInputEvent);
if (m_rect.Contains(pt))
return WidgetHandleStates::kActivated;
else
return WidgetHandleStates::kIgnored;
}
return WidgetHandleStates::kCaptured;
}
else
{
if (evt.IsLMouseDownEvent())
{
const Point pt = m_window->MouseToLocal(evt.m_vosEvent.m_event.m_mouseInputEvent);
if (m_rect.Contains(pt))
{
m_haveMouseDown = true;
return WidgetHandleStates::kCaptured;
}
else
return WidgetHandleStates::kIgnored;
}
}
return WidgetHandleStates::kIgnored;
}
}

View File

@@ -11,7 +11,7 @@ namespace PortabilityLayer
RadioButtonWidget(const WidgetBasicState &state);
~RadioButtonWidget();
bool Init(const WidgetBasicState &state) override;
bool Init(const WidgetBasicState &state, const void *additionalData) override;
void DrawControl(DrawSurface *surface) override;
void SetString(const PLPasStr &str) override;

View File

@@ -0,0 +1,18 @@
#pragma once
namespace RegionIDs
{
enum RegionID
{
kNone,
kMenuBar = 1,
kContent,
kTitleBar,
kClose,
kResize,
};
}
typedef RegionIDs::RegionID RegionID_t;

View File

@@ -28,7 +28,7 @@ namespace PortabilityLayer
DrawControl(m_window->GetDrawSurface());
}
bool ScrollBarWidget::Init(const WidgetBasicState &state)
bool ScrollBarWidget::Init(const WidgetBasicState &state, const void *additionalData)
{
m_min = state.m_min;
m_max = state.m_max;

View File

@@ -12,7 +12,7 @@ namespace PortabilityLayer
public:
explicit ScrollBarWidget(const WidgetBasicState &state);
bool Init(const WidgetBasicState &state) override;
bool Init(const WidgetBasicState &state, const void *additionalData) override;
void OnEnabledChanged() override;
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt) override;

View File

@@ -45,7 +45,7 @@ namespace PortabilityLayer
class Widget
{
public:
virtual bool Init(const WidgetBasicState &state) = 0;
virtual bool Init(const WidgetBasicState &state, const void *additionalData) = 0;
virtual void Destroy() = 0;
virtual WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt);
virtual int16_t Capture(const Point &pos, WidgetUpdateCallback_t callback);
@@ -125,7 +125,7 @@ namespace PortabilityLayer
Widget::BaseRelease(static_cast<T*>(this));
}
static T *Create(const WidgetBasicState &state)
static T *Create(const WidgetBasicState &state, const void *additionalData)
{
void *storage = Widget::BaseAlloc(sizeof(T));
if (!storage)
@@ -138,7 +138,7 @@ namespace PortabilityLayer
(void)downcastWidget;
Widget *widget = widgetT;
if (!widget->Init(state))
if (!widget->Init(state, additionalData))
{
widget->Destroy();
return nullptr;

View File

@@ -227,6 +227,7 @@
<ClInclude Include="PLLittleEndian.h" />
<ClInclude Include="PLPopupMenuWidget.h" />
<ClInclude Include="PLRadioButtonWidget.h" />
<ClInclude Include="PLRegions.h" />
<ClInclude Include="PLScrollBarWidget.h" />
<ClInclude Include="PLUnalignedPtr.h" />
<ClInclude Include="PLWidgets.h" />
@@ -340,7 +341,6 @@
<ClCompile Include="PLAppleEvents.cpp" />
<ClCompile Include="PLApplication.cpp" />
<ClCompile Include="PLButtonWidget.cpp" />
<ClCompile Include="PLCheckboxWidget.cpp" />
<ClCompile Include="PLControlDefinitions.cpp" />
<ClCompile Include="PLCore.cpp" />
<ClCompile Include="PLCTabReducer.cpp" />
@@ -360,7 +360,6 @@
<ClCompile Include="PLPopupMenuWidget.cpp" />
<ClCompile Include="PLQDOffscreen.cpp" />
<ClCompile Include="PLQDraw.cpp" />
<ClCompile Include="PLRadioButtonWidget.cpp" />
<ClCompile Include="PLResourceManager.cpp" />
<ClCompile Include="PLResources.cpp" />
<ClCompile Include="PLScrollBarWidget.cpp" />

View File

@@ -411,9 +411,6 @@
<ClInclude Include="PLWidgets.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PLButtonWidget.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PLIconWidget.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -489,6 +486,12 @@
<ClInclude Include="UTF16.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PLButtonWidget.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PLRegions.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CFileStream.cpp">
@@ -707,9 +710,6 @@
<ClCompile Include="PLCTabReducer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PLButtonWidget.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PLIconWidget.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -731,12 +731,6 @@
<ClCompile Include="PLPopupMenuWidget.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PLCheckboxWidget.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PLRadioButtonWidget.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PLKeyEncoding.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -770,5 +764,8 @@
<ClCompile Include="UTF16.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PLButtonWidget.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -86,6 +86,26 @@ namespace PortabilityLayer
static const int kLightGray = 221;
};
class AlertWindowChromeTheme final : public WindowChromeThemeSingleton<AlertWindowChromeTheme>
{
public:
void GetChromePadding(const WindowImpl *window, uint16_t padding[WindowChromeSides::kCount]) const override;
void RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const override;
bool GetChromeInteractionZone(const WindowImpl *window, const Vec2i &point, RegionID_t &outRegion) const override;
bool GetChromeRegionRect(const WindowImpl *window, RegionID_t region, Rect2i &outRect) const override;
void UpdateRegionChromeState(const WindowImpl *window, RegionID_t region, const void *data) const override;
private:
void RenderChromeTop(WindowImpl *window, DrawSurface *surface) const;
void RenderChromeLeft(WindowImpl *window, DrawSurface *surface) const;
void RenderChromeBottom(WindowImpl *window, DrawSurface *surface) const;
void RenderChromeRight(WindowImpl *window, DrawSurface *surface) const;
static const RGBAColor kDarkColor;
static const RGBAColor kMidColor;
static const RGBAColor kLightColor;
};
class WindowImpl final : public Window
{
public:
@@ -145,6 +165,8 @@ namespace PortabilityLayer
bool HandleCloseBoxClick(Window *window, const Point &startPoint) override;
void SetWindowTitle(Window *window, const PLPasStr &title) override;
Rect2i GetWindowFullRect(Window *window) const override;
bool GetWindowChromeInteractionZone(Window *window, const Vec2i &point, RegionID_t &outRegion) const override;
void SwapExclusiveWindow(Window *& windowRef) override;
void SetResizeInProgress(Window *window, const PortabilityLayer::Vec2i &size) override;
void ClearResizeInProgress() override;
@@ -166,6 +188,8 @@ namespace PortabilityLayer
WindowImpl *m_windowStackTop;
WindowImpl *m_windowStackBottom;
WindowImpl *m_exclusiveWindow;
Rect2i m_resizeInProgressRect;
DrawSurface m_resizeInProgressHorizontalBar;
DrawSurface m_resizeInProgressVerticalBar;
@@ -585,6 +609,144 @@ namespace PortabilityLayer
}
}
//---------------------------------------------------------------------------
// Alert chrome theme
const RGBAColor AlertWindowChromeTheme::kDarkColor = RGBAColor::Create(255, 51, 51, 255);
const RGBAColor AlertWindowChromeTheme::kMidColor = RGBAColor::Create(255, 153, 51, 255);
const RGBAColor AlertWindowChromeTheme::kLightColor = RGBAColor::Create(255, 204, 51, 255);
void AlertWindowChromeTheme::GetChromePadding(const WindowImpl *window, uint16_t padding[WindowChromeSides::kCount]) const
{
padding[WindowChromeSides::kTop] = 6;
padding[WindowChromeSides::kBottom] = 6;
padding[WindowChromeSides::kLeft] = 6;
padding[WindowChromeSides::kRight] = 6;
}
bool AlertWindowChromeTheme::GetChromeInteractionZone(const WindowImpl *window, const Vec2i &point, RegionID_t &outRegion) const
{
return false;
}
bool AlertWindowChromeTheme::GetChromeRegionRect(const WindowImpl *window, RegionID_t region, Rect2i &outRect) const
{
return false;
}
void AlertWindowChromeTheme::UpdateRegionChromeState(const WindowImpl *window, RegionID_t region, const void *data) const
{
}
void AlertWindowChromeTheme::RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const
{
switch (chromeSide)
{
case WindowChromeSides::kTop:
RenderChromeTop(window, surface);
break;
case WindowChromeSides::kLeft:
RenderChromeLeft(window, surface);
break;
case WindowChromeSides::kBottom:
RenderChromeBottom(window, surface);
break;
case WindowChromeSides::kRight:
RenderChromeRight(window, surface);
break;
default:
break;
}
}
void AlertWindowChromeTheme::RenderChromeTop(WindowImpl *window, DrawSurface *surface) const
{
const Rect rect = (*surface->m_port.GetPixMap())->m_rect;
surface->SetForeColor(kMidColor);
surface->FillRect(rect);
surface->SetForeColor(StdColors::Black());
surface->FillRect(Rect::Create(rect.top, rect.left, rect.top + 1, rect.right));
surface->FillRect(Rect::Create(rect.top, rect.left, rect.bottom, 1));
surface->FillRect(Rect::Create(rect.top, rect.right - 1, rect.bottom, rect.right));
surface->FillRect(Rect::Create(rect.bottom - 1, rect.left + 5, rect.bottom, rect.right - 5));
surface->SetForeColor(kDarkColor);
surface->FillRect(Rect::Create(rect.bottom - 2, rect.left + 4, rect.bottom - 1, rect.right - 5));
surface->FillRect(Rect::Create(rect.bottom - 2, rect.left + 4, rect.bottom, rect.left + 5));
surface->FillRect(Rect::Create(rect.top + 2, rect.right - 2, rect.bottom, rect.right - 1));
surface->SetForeColor(kLightColor);
surface->FillRect(Rect::Create(rect.top + 1, rect.left + 1, rect.bottom, rect.left + 2));
surface->FillRect(Rect::Create(rect.top + 1, rect.left + 1, rect.top + 2, rect.right - 2));
surface->FillRect(Rect::Create(rect.bottom - 1, rect.right - 5, rect.bottom, rect.right - 4));
}
void AlertWindowChromeTheme::RenderChromeLeft(WindowImpl *window, DrawSurface *surface) const
{
const Rect rect = (*surface->m_port.GetPixMap())->m_rect;
surface->SetForeColor(StdColors::Black());
surface->FillRect(Rect::Create(rect.top, rect.right - 6, rect.bottom, rect.right - 5));
surface->FillRect(Rect::Create(rect.top, rect.right - 1, rect.bottom, rect.right));
surface->SetForeColor(kLightColor);
surface->FillRect(Rect::Create(rect.top, rect.right - 5, rect.bottom, rect.right - 4));
surface->SetForeColor(kDarkColor);
surface->FillRect(Rect::Create(rect.top, rect.right - 2, rect.bottom, rect.right - 1));
surface->SetForeColor(kMidColor);
surface->FillRect(Rect::Create(rect.top, rect.right - 4, rect.bottom, rect.right - 2));
}
void AlertWindowChromeTheme::RenderChromeBottom(WindowImpl *window, DrawSurface *surface) const
{
const Rect rect = (*surface->m_port.GetPixMap())->m_rect;
surface->SetForeColor(kMidColor);
surface->FillRect(Rect::Create(rect.top, rect.left + 1, rect.bottom - 1, rect.left + 5));
surface->FillRect(Rect::Create(rect.bottom - 4, rect.left + 5, rect.bottom - 2, rect.right - 4));
surface->FillRect(Rect::Create(rect.top, rect.right - 4, rect.bottom - 2, rect.right - 2));
surface->SetForeColor(StdColors::Black());
surface->FillRect(Rect::Create(rect.top, rect.left, rect.bottom, rect.left + 1));
surface->FillRect(Rect::Create(rect.bottom - 1, rect.left, rect.bottom, rect.right));
surface->FillRect(Rect::Create(rect.top, rect.right - 1, rect.bottom, rect.right));
surface->FillRect(Rect::Create(rect.top, rect.left + 5, rect.bottom - 5, rect.left + 6));
surface->FillRect(Rect::Create(rect.top, rect.right - 6, rect.bottom - 5, rect.right - 5));
surface->FillRect(Rect::Create(rect.bottom - 6, rect.left + 6, rect.bottom - 5, rect.right - 6));
surface->SetForeColor(kLightColor);
surface->FillRect(Rect::Create(rect.top, rect.right - 5, rect.bottom - 5, rect.right - 4));
surface->FillRect(Rect::Create(rect.top, rect.left + 1, rect.bottom - 2, rect.left + 2));
surface->FillRect(Rect::Create(rect.bottom - 5, rect.left + 5, rect.bottom - 4, rect.right - 4));
surface->SetForeColor(kDarkColor);
surface->FillRect(Rect::Create(rect.bottom - 2, rect.left + 2, rect.bottom - 1, rect.right - 2));
surface->FillRect(Rect::Create(rect.top, rect.left + 4, rect.bottom - 5, rect.left + 5));
surface->FillRect(Rect::Create(rect.top, rect.right - 2, rect.bottom - 1, rect.right - 1));
}
void AlertWindowChromeTheme::RenderChromeRight(WindowImpl *window, DrawSurface *surface) const
{
const Rect rect = (*surface->m_port.GetPixMap())->m_rect;
surface->SetForeColor(StdColors::Black());
surface->FillRect(Rect::Create(rect.top, rect.right - 6, rect.bottom, rect.right - 5));
surface->FillRect(Rect::Create(rect.top, rect.right - 1, rect.bottom, rect.right));
surface->SetForeColor(kLightColor);
surface->FillRect(Rect::Create(rect.top, rect.right - 5, rect.bottom, rect.right - 4));
surface->SetForeColor(kDarkColor);
surface->FillRect(Rect::Create(rect.top, rect.right - 2, rect.bottom, rect.right - 1));
surface->SetForeColor(kMidColor);
surface->FillRect(Rect::Create(rect.top, rect.right - 4, rect.bottom, rect.right - 2));
}
//---------------------------------------------------------------------------
WindowImpl::WindowImpl()
: m_windowAbove(nullptr)
@@ -627,6 +789,8 @@ namespace PortabilityLayer
if (m_styleFlags & WindowStyleFlags::kTitleBar)
m_chromeTheme = GenericWindowChromeTheme::GetInstance();
else if (m_styleFlags & WindowStyleFlags::kAlert)
m_chromeTheme = AlertWindowChromeTheme::GetInstance();
Rect chromeBounds[WindowChromeSides::kCount];
GetChromeDimensions(bounds.Width(), bounds.Height(), chromeBounds);
@@ -776,6 +940,7 @@ namespace PortabilityLayer
, m_windowStackBottom(nullptr)
, m_resizeInProgressRect(Rect2i(0, 0, 0, 0))
, m_isResizeInProgress(false)
, m_exclusiveWindow(nullptr)
{
}
@@ -913,6 +1078,8 @@ namespace PortabilityLayer
{
WindowImpl *windowImpl = static_cast<WindowImpl*>(window);
assert(windowImpl != m_exclusiveWindow);
DetachWindow(window);
if (PortabilityLayer::QDManager::GetInstance()->GetPort() == &windowImpl->m_surface.m_port)
@@ -1035,6 +1202,18 @@ 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]);
}
bool WindowManagerImpl::GetWindowChromeInteractionZone(Window *window, const Vec2i &point, RegionID_t &outRegion) const
{
return static_cast<WindowImpl*>(window)->GetChromeInteractionZone(point, outRegion);
}
void WindowManagerImpl::SwapExclusiveWindow(Window *& windowRef)
{
Window *temp = m_exclusiveWindow;
m_exclusiveWindow = static_cast<WindowImpl*>(windowRef);
windowRef = temp;
}
void WindowManagerImpl::SetResizeInProgress(Window *window, const PortabilityLayer::Vec2i &size)
{
ResetResizeInProgressSurfaces();
@@ -1095,10 +1274,10 @@ namespace PortabilityLayer
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());
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, nullptr);
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, nullptr);
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(), nullptr);
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(), nullptr);
}
}
@@ -1198,6 +1377,11 @@ namespace PortabilityLayer
if (!window->IsVisible())
return;
GpDisplayDriverSurfaceEffects effects;
if (m_exclusiveWindow != nullptr && m_exclusiveWindow != window)
effects.m_darken = true;
DrawSurface &graf = window->m_surface;
graf.PushToDDSurface(displayDriver);
@@ -1205,8 +1389,7 @@ namespace PortabilityLayer
const PixMap *pixMap = *graf.m_port.GetPixMap();
const uint16_t width = pixMap->m_rect.Width();
const uint16_t height = pixMap->m_rect.Height();
displayDriver->DrawSurface(graf.m_ddSurface, window->m_wmX, window->m_wmY, width, height);
displayDriver->DrawSurface(graf.m_ddSurface, window->m_wmX, window->m_wmY, width, height, &effects);
if (!window->IsBorderless())
{
@@ -1231,7 +1414,7 @@ namespace PortabilityLayer
chromeSurface->PushToDDSurface(displayDriver);
displayDriver->DrawSurface(chromeSurface->m_ddSurface, chromeOrigins[i].m_x, chromeOrigins[i].m_y, chromeDimensions[i].m_x, chromeDimensions[i].m_y);
displayDriver->DrawSurface(chromeSurface->m_ddSurface, chromeOrigins[i].m_x, chromeOrigins[i].m_y, chromeDimensions[i].m_x, chromeDimensions[i].m_y, &effects);
}
}
}

View File

@@ -2,6 +2,8 @@
#include <stdint.h>
#include "PLRegions.h"
struct Window;
struct DrawSurface;
struct GDevice;
@@ -33,6 +35,8 @@ namespace PortabilityLayer
virtual bool HandleCloseBoxClick(Window *window, const Point &startPoint) = 0;
virtual void SetWindowTitle(Window *window, const PLPasStr &title) = 0;
virtual Rect2i GetWindowFullRect(Window *window) const = 0;
virtual bool GetWindowChromeInteractionZone(Window *window, const Vec2i &point, RegionID_t &outRegion) const = 0;
virtual void SwapExclusiveWindow(Window *& windowRef) = 0;
virtual void SetResizeInProgress(Window *window, const PortabilityLayer::Vec2i &size) = 0;
virtual void ClearResizeInProgress() = 0;