Files
Aerofoil/GpApp/About.cpp
2020-10-24 23:56:04 -04:00

767 lines
24 KiB
C++

//============================================================================
//----------------------------------------------------------------------------
// About.c
//----------------------------------------------------------------------------
//============================================================================
#include "PLArrayView.h"
#include "PLKeyEncoding.h"
#include "PLControlDefinitions.h"
#include "FontFamily.h"
#include "PLButtonWidget.h"
#include "PLLabelWidget.h"
#include "PLNumberFormatting.h"
#include "PLResources.h"
#include "PLSound.h"
#include "PLPasStr.h"
#include "PLScrollBarWidget.h"
#include "PLStandardColors.h"
#include "PLSysCalls.h"
#include "PLTimeTaggedVOSEvent.h"
#include "PLWidgets.h"
#include "About.h"
#include "DialogManager.h"
#include "DialogUtils.h"
#include "Environ.h"
#include "Externs.h"
#include "GpApplicationName.h"
#include "GpBuildVersion.h"
#include "HostSystemServices.h"
#include "RenderedFont.h"
#include "GpRenderedFontMetrics.h"
#include "ResolveCachingColor.h"
#include "ResourceManager.h"
#include "ScanlineMask.h"
#include "WindowDef.h"
#include "WindowManager.h"
static void HiLiteOkayButton (DrawSurface *surface);
static void UnHiLiteOkayButton (DrawSurface *surface);
static void UpdateMainPict (Dialog *);
static int16_t AboutFilter(void *context, Dialog *, const TimeTaggedVOSEvent *evt);
static int16_t AboutFrameworkFilter(void *context, Dialog *, const TimeTaggedVOSEvent *evt);
static int16_t LicenseReaderFilter(void *context, Dialog *, const TimeTaggedVOSEvent *evt);
static void DrawLicenseReader(Window *window);
void DoLicenseReader(int licenseResID);
static Point okayButtLowerV, okayButtUpperV;
static Rect okayButtonBounds, mainPICTBounds;
static Boolean okayButtIsHiLit, clickedDownInOkay;
struct LicenseReaderLine
{
PortabilityLayer::PascalStr<80> m_text;
};
static const unsigned int kLicenseReaderPointHistoryLength = 3;
static Boolean licenseReaderIsScrolling;
static Point licenseReaderPointHistory[kLicenseReaderPointHistoryLength];
static int32_t licenseReaderVelocity;
static unsigned int licenseReaderTextScroll;
static unsigned int licenseReaderTextScrollMax;
static unsigned int licenseReaderNumLines;
static THandle<LicenseReaderLine> licenseReaderLines;
static const unsigned int kLicenseReaderTextSpacing = 10;
static const Rect licenseReaderTextRect = Rect::Create(16, 16, 344, 496);
static PortabilityLayer::ScrollBarWidget *licenseReaderScrollBarWidget;
static void InitLicenseReader(unsigned int numLines)
{
for (unsigned int i = 0; i < kLicenseReaderPointHistoryLength; i++)
licenseReaderPointHistory[i] = Point::Create(0, 0);
licenseReaderIsScrolling = false;
licenseReaderTextScroll = 0;
licenseReaderVelocity = 0;
licenseReaderTextScrollMax = numLines * kLicenseReaderTextSpacing;
if (licenseReaderTextScrollMax < licenseReaderTextRect.Height())
licenseReaderTextScrollMax = 0;
else
licenseReaderTextScrollMax -= licenseReaderTextRect.Height();
licenseReaderNumLines = numLines;
licenseReaderScrollBarWidget = nullptr;
}
//============================================================== Functions
//-------------------------------------------------------------- DoAbout
// Brings up the About dialog box.
void DoAbout (void)
{
#define kAboutDialogID 150 // res ID of About dialog
#define kTextItemVers 2 // item number of version text
#define kPictItemMain 4 // item number of main PICT
Dialog *aboutDialog;
Str255 longVersion;
StringPtr messagePtr;
VersRecHndl version;
ControlHandle itemHandle;
short hit;
aboutDialog = PortabilityLayer::DialogManager::GetInstance()->LoadDialog(kAboutDialogID, PL_GetPutInFrontWindowPtr(), nullptr);
// if (aboutDialog == nil)
// RedAlert(kErrDialogDidntLoad);
version = PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('vers', 1).StaticCast<VersionRecord>();
if (version != nil)
{
messagePtr = (**version).shortVersion + 1 + (**version).shortVersion[0];
memcpy(&longVersion, messagePtr, ((UInt8)*messagePtr) + 1);
SetDialogString(aboutDialog, kTextItemVers, longVersion);
}
okayButtonBounds = aboutDialog->GetItems()[kOkayButton - 1].GetWidget()->GetRect();
okayButtUpperV = Point::Create(okayButtonBounds.left + 45, okayButtonBounds.top + 1);
okayButtLowerV = Point::Create(okayButtUpperV.h - 28, okayButtUpperV.v + 60);
okayButtIsHiLit = false; // Initially, button is not hilit
clickedDownInOkay = false; // Initially, didn't click in okay button
mainPICTBounds = aboutDialog->GetItems()[kPictItemMain - 1].GetWidget()->GetRect();
UpdateMainPict(aboutDialog);
do // Loop until user wants to exit
{
hit = aboutDialog->ExecuteModal(nullptr, AboutFilter);
}
while (hit != kOkayButton);
aboutDialog->Destroy();
}
void DoLicenseReader(int resID)
{
static const int kLicenseReaderDialogTemplateID = 2006;
THandle<uint8_t> licenseTextHandle = PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('LICS', resID).StaticCast<uint8_t>();
if (!licenseTextHandle)
return;
// Count lines
unsigned int numLines = 1;
const uint8_t *licenseText = *licenseTextHandle;
const size_t licenseTextLength = licenseTextHandle.MMBlock()->m_size;
for (size_t i = 0; i < licenseTextLength; i++)
{
if (licenseText[i] == '\n')
numLines++;
}
licenseReaderLines = NewHandle(sizeof(LicenseReaderLine) * numLines).StaticCast<LicenseReaderLine>();
if (!licenseReaderLines)
{
licenseTextHandle.Dispose();
return;
}
LicenseReaderLine *lines = *licenseReaderLines;
unsigned int lineIndex = 0;
size_t lineStart = 0;
for (size_t i = 0; i < licenseTextLength; i++)
{
if (licenseText[i] == '\n')
{
assert(i - lineStart <= 80);
lines[lineIndex++].m_text.Set(i - lineStart, reinterpret_cast<const char*>(licenseText + lineStart));
lineStart = i + 1;
}
}
assert(licenseTextLength - lineStart <= 80);
lines[lineIndex++].m_text.Set(licenseTextLength - lineStart, reinterpret_cast<const char*>(licenseText + lineStart));
assert(lineIndex == numLines);
licenseTextHandle.Dispose();
const Rect windowRect = Rect::Create(0, 0, 396, 528);
PortabilityLayer::WindowDef wdef = PortabilityLayer::WindowDef::Create(windowRect, PortabilityLayer::WindowStyleFlags::kAlert, true, 0, 0, PSTR(""));
PortabilityLayer::DialogManager *dialogManager = PortabilityLayer::DialogManager::GetInstance();
Dialog *dialog = dialogManager->LoadDialogFromTemplate(kLicenseReaderDialogTemplateID, windowRect, true, false, 0, 0, PL_GetPutInFrontWindowPtr(), PSTR(""), nullptr);
DrawDefaultButton(dialog);
int16_t hit = 0;
InitLicenseReader(numLines);
DrawLicenseReader(dialog->GetWindow());
if (licenseReaderTextScrollMax != 0)
{
PortabilityLayer::WidgetBasicState state;
state.m_rect = Rect::Create(licenseReaderTextRect.top, licenseReaderTextRect.right, licenseReaderTextRect.bottom, licenseReaderTextRect.right + 16);
state.m_refConstant = 2;
state.m_window = dialog->GetWindow();
state.m_max = licenseReaderTextScrollMax;
state.m_state = 0;
licenseReaderScrollBarWidget = PortabilityLayer::ScrollBarWidget::Create(state, nullptr);
}
dialog->GetWindow()->DrawControls();
do
{
hit = dialog->ExecuteModal(nullptr, LicenseReaderFilter);
} while (hit != kOkayButton);
dialog->Destroy();
licenseReaderLines.Dispose();
}
void DoAboutOpenSource(void)
{
static const int kExportSourceItem = 2;
static const int kAerofoilLicenseButton = 4;
static const int kGliderPROLicenseButton = 6;
static const int kOpenSansLicenseButton = 8;
static const int kRobotoMonoLicenseButton = 10;
static const int kGochiHandLicenseButton = 12;
static const int kLibIConvLicenseButton = 14;
static const int kRapidJSONLicenseButton = 16;
static const int kZLibLicenseButton = 18;
static const int kFreeTypeLicenseButton = 20;
static const int kSDLLicenseButton = 22;
static const int kLicenseResourceApache = 1000;
static const int kLicenseResourceGPLv2 = 1001;
static const int kLicenseResourceLGPLv3 = 1002;
static const int kLicenseResourceOFL = 1003;
static const int kLicenseResourceRapidJSON = 1004;
static const int kLicenseResourceZLib = 1005;
static const int kLicenseResourceSDL = 1006;
static const int kAboutOpenSourceDialogTemplateID = 2005;
const Rect windowRect = Rect::Create(0, 0, 324, 512);
PortabilityLayer::WindowDef wdef = PortabilityLayer::WindowDef::Create(windowRect, PortabilityLayer::WindowStyleFlags::kAlert, true, 0, 0, PSTR(""));
PortabilityLayer::DialogManager *dialogManager = PortabilityLayer::DialogManager::GetInstance();
Dialog *dialog = dialogManager->LoadDialogFromTemplate(kAboutOpenSourceDialogTemplateID, windowRect, true, false, 0, 0, PL_GetPutInFrontWindowPtr(), PSTR(""), nullptr);
DrawDefaultButton(dialog);
if (thisMac.isTouchscreen)
dialog->GetItems()[kExportSourceItem - 1].GetWidget()->SetEnabled(true);
int16_t hit = 0;
do
{
hit = dialog->ExecuteModal(nullptr, AboutFrameworkFilter);
switch (hit)
{
case kExportSourceItem:
DoExportSourceCode();
break;
case kAerofoilLicenseButton:
case kGliderPROLicenseButton:
DoLicenseReader(kLicenseResourceGPLv2);
break;
case kOpenSansLicenseButton:
case kRobotoMonoLicenseButton:
DoLicenseReader(kLicenseResourceApache);
break;
case kGochiHandLicenseButton:
DoLicenseReader(kLicenseResourceOFL);
break;
case kLibIConvLicenseButton:
case kFreeTypeLicenseButton:
DoLicenseReader(kLicenseResourceLGPLv3);
break;
case kZLibLicenseButton:
DoLicenseReader(kLicenseResourceZLib);
break;
case kSDLLicenseButton:
DoLicenseReader(kLicenseResourceSDL);
break;
case kRapidJSONLicenseButton:
DoLicenseReader(kLicenseResourceRapidJSON);
break;
default:
break;
}
} while (hit != kOkayButton);
dialog->Destroy();
}
void DoAboutFramework (void)
{
static const int kAboutFrameworkDialogTemplateID = 2000;
static const int kAboutOpenSourceButton = 2;
const Rect windowRect = Rect::Create(0, 0, 272, 450);
PortabilityLayer::WindowDef wdef = PortabilityLayer::WindowDef::Create(windowRect, PortabilityLayer::WindowStyleFlags::kAlert, true, 0, 0, PSTR(""));
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
PortabilityLayer::RenderedFont *font = GetApplicationFont(12, PortabilityLayer::FontFamilyFlag_Bold, true);
PortabilityLayer::RenderedFont *fontLight = GetApplicationFont(8, PortabilityLayer::FontFamilyFlag_None, true);
int16_t verticalPoint = 16 + font->GetMetrics().m_ascent;
int16_t horizontalOffset = 16;
const int16_t spacing = 12;
PortabilityLayer::DialogManager *dialogManager = PortabilityLayer::DialogManager::GetInstance();
Dialog *dialog = dialogManager->LoadDialogFromTemplate(kAboutFrameworkDialogTemplateID, windowRect, true, false, 0, 0, PL_GetPutInFrontWindowPtr(), PSTR(""), nullptr);
#if !GP_DEBUG_CONFIG
#define ABOUT_DIALOG_CONFIGURATION_TAG "Release"
#else
#define ABOUT_DIALOG_CONFIGURATION_TAG "Debug"
#endif
Window *window = dialog->GetWindow();
DrawSurface *surface = window->GetDrawSurface();
surface->DrawString(Point::Create(horizontalOffset, verticalPoint + spacing * 0), PSTR(GP_APPLICATION_NAME " " GP_APPLICATION_VERSION_STRING " \xa9" GP_APPLICATION_COPYRIGHT_STRING), blackColor, font);
surface->DrawString(Point::Create(horizontalOffset, verticalPoint + spacing * 2), PSTR(GP_APPLICATION_NAME " is an unoffical third-party port of Glider PRO\xaa."), blackColor, font);
surface->DrawString(Point::Create(horizontalOffset, verticalPoint + spacing * 4), PSTR("This software is not maintained by, supported by, endorsed by, or"), blackColor, font);
surface->DrawString(Point::Create(horizontalOffset, verticalPoint + spacing * 5), PSTR("otherwise associated with the authors and publishers of Glider PRO\xaa."), blackColor, font);
surface->DrawString(Point::Create(horizontalOffset, verticalPoint + spacing * 7), PSTR("Please do not contact any of them regarding issues that you have"), blackColor, font);
surface->DrawString(Point::Create(horizontalOffset, verticalPoint + spacing * 8), PSTR("with " GP_APPLICATION_NAME "."), blackColor, font);
surface->DrawString(Point::Create(horizontalOffset, verticalPoint + spacing * 10), PSTR("If you would like to contribute to this project, visit:"), blackColor, font);
surface->DrawString(Point::Create(horizontalOffset, verticalPoint + spacing * 11), PSTR(GP_APPLICATION_WEBSITE_STRING), blackColor, font);
surface->DrawString(Point::Create(horizontalOffset, verticalPoint + spacing * 13), PSTR("To report a problem or request support, submit an issue via"), blackColor, font);
surface->DrawString(Point::Create(horizontalOffset, verticalPoint + spacing * 14), PSTR("the website above."), blackColor, font);
surface->DrawString(Point::Create(horizontalOffset, verticalPoint + spacing * 16), PSTR("For more information, please see the accompanying documentation."), blackColor, font);
surface->DrawString(Point::Create(horizontalOffset, windowRect.bottom - 16), PSTR("Build: " __DATE__ " " __TIME__ " " ABOUT_DIALOG_CONFIGURATION_TAG), blackColor, fontLight);
DrawDefaultButton(dialog);
int16_t hit = 0;
do
{
hit = dialog->ExecuteModal(nullptr, AboutFrameworkFilter);
if (hit == kAboutOpenSourceButton)
DoAboutOpenSource();
} while (hit != kOkayButton);
dialog->Destroy();
}
//============================================================== Static Functions
//-------------------------------------------------------------- HiLiteOkayButton
// Draws my pseudo-button to appear as though it is clicked on.
static void HiLiteOkayButton (DrawSurface *surface)
{
#define kOkayButtPICTHiLit 151 // res ID of unhilit button PICT
THandle<BitmapImage> thePict;
if (!okayButtIsHiLit)
{
thePict = PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('PICT', kOkayButtPICTHiLit).StaticCast<BitmapImage>();
if (thePict != nil)
{
surface->DrawPicture(thePict, okayButtonBounds);
thePict.Dispose();
okayButtIsHiLit = true;
}
}
}
//-------------------------------------------------------------- UnHiLiteOkayButton
// Draws my pseudo-button normal (not clicked on).
static void UnHiLiteOkayButton (DrawSurface *surface)
{
#define kOkayButtPICTNotHiLit 150 // res ID of hilit button PICT
THandle<BitmapImage> thePict;
if (okayButtIsHiLit)
{
thePict = PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('PICT', kOkayButtPICTNotHiLit).StaticCast<BitmapImage>();
if (thePict != nil)
{
surface->DrawPicture(thePict, okayButtonBounds);
thePict.Dispose();
okayButtIsHiLit = false;
}
}
}
//-------------------------------------------------------------- UpdateMainPict
// Redraws the main graphic in the dialog (in response to an update event).
static void UpdateMainPict (Dialog *theDial)
{
Str255 theStr, theStr2;
uint64_t freeMemory;
freeMemory = PortabilityLayer::HostSystemServices::GetInstance()->GetFreeMemoryCosmetic();
PasStringCopy(PSTR("Memory: "), theStr); // display free memory
long totalSize = static_cast<long>(freeMemory / 1024);
NumToString(totalSize, theStr2);
PasStringConcat(theStr, theStr2);
PasStringConcat(theStr, PSTR("K"));
DrawDialogUserText2(theDial, 7, theStr);
PasStringCopy(PSTR("Screen: "), theStr); // display screen size/depth
NumToString((long)(thisMac.fullScreen.right - thisMac.fullScreen.left), theStr2);
PasStringConcat(theStr, theStr2);
PasStringConcat(theStr, PSTR("x"));
NumToString((long)(thisMac.fullScreen.bottom - thisMac.fullScreen.top), theStr2);
PasStringConcat(theStr, theStr2);
PasStringConcat(theStr, PSTR("x"));
NumToString((long)thisMac.isDepth, theStr2);
PasStringConcat(theStr, theStr2);
DrawDialogUserText2(theDial, 8, theStr);
}
static bool PointIsInDiagonalOkayButton(const Point &pt)
{
const Point upperVPt = pt - okayButtUpperV;
const Point lowerVPt = pt - okayButtLowerV;
const bool edge1 = (upperVPt.h + upperVPt.v) >= 0;
const bool edge2 = (-upperVPt.h + upperVPt.v) >= 0;
const bool edge3 = (lowerVPt.h - lowerVPt.v) >= 0;
const bool edge4 = (-lowerVPt.h - lowerVPt.v) >= 0;
return edge1 && edge2 && edge3 && edge4;
}
//-------------------------------------------------------------- AboutFilter
// Dialog filter for the About dialog.
static int16_t AboutFilter(void *context, Dialog *dialog, const TimeTaggedVOSEvent *evt)
{
bool handledIt = false;
int16_t hit = -1;
if (!evt)
return -1;
Window *window = dialog->GetWindow();
DrawSurface *surface = window->GetDrawSurface();
if (evt->IsKeyDownEvent())
{
switch (PackVOSKeyCode(evt->m_vosEvent.m_event.m_keyboardInputEvent))
{
case PL_KEY_SPECIAL(kEnter):
case PL_KEY_NUMPAD_SPECIAL(kEnter):
HiLiteOkayButton(surface);
PLSysCalls::Sleep(8);
UnHiLiteOkayButton(surface);
hit = kOkayButton;
handledIt = true;
break;
default:
handledIt = false;
break;
}
}
else if (evt->m_vosEvent.m_eventType == GpVOSEventTypes::kMouseInput)
{
const GpMouseInputEvent &mouseEvt = evt->m_vosEvent.m_event.m_mouseInputEvent;
const Point mousePt = window->MouseToLocal(mouseEvt);
if (mouseEvt.m_eventType == GpMouseEventTypes::kDown)
{
if (PointIsInDiagonalOkayButton(mousePt))
{
HiLiteOkayButton(surface);
clickedDownInOkay = true;
handledIt = false;
}
else
handledIt = false;
}
else if (mouseEvt.m_eventType == GpMouseEventTypes::kUp)
{
if (PointIsInDiagonalOkayButton(mousePt) && clickedDownInOkay)
{
UnHiLiteOkayButton(surface);
hit = kOkayButton;
handledIt = true;
}
else
{
clickedDownInOkay = false;
handledIt = false;
}
}
else if (mouseEvt.m_eventType == GpMouseEventTypes::kMove)
{
if (clickedDownInOkay)
{
if (PointIsInDiagonalOkayButton(mousePt))
HiLiteOkayButton(surface);
else
UnHiLiteOkayButton(surface);
}
}
}
if (!handledIt)
return -1;
return hit;
}
//-------------------------------------------------------------- AboutFrameworkFilter
// Dialog filter for the About Framework dialog.
static int16_t AboutFrameworkFilter(void *context, Dialog *dialog, const TimeTaggedVOSEvent *evt)
{
bool handledIt = false;
int16_t hit = -1;
if (!evt)
return -1;
Window *window = dialog->GetWindow();
DrawSurface *surface = window->GetDrawSurface();
if (evt->IsKeyDownEvent())
{
switch (PackVOSKeyCode(evt->m_vosEvent.m_event.m_keyboardInputEvent))
{
case PL_KEY_SPECIAL(kEnter):
case PL_KEY_NUMPAD_SPECIAL(kEnter):
dialog->GetItems()[kOkayButton - 1].GetWidget()->SetHighlightStyle(kControlButtonPart, true);
PLSysCalls::Sleep(8);
dialog->GetItems()[kOkayButton - 1].GetWidget()->SetHighlightStyle(kControlButtonPart, false);
hit = kOkayButton;
handledIt = true;
break;
default:
handledIt = false;
break;
}
}
if (!handledIt)
return -1;
return hit;
}
void DrawLicenseReader(Window *window)
{
PortabilityLayer::RenderedFont *rfont = GetMonospaceFont(10, PortabilityLayer::FontFamilyFlag_None, true);
if (!rfont)
return;
PortabilityLayer::ResolveCachingColor whiteColor(StdColors::White());
PortabilityLayer::ResolveCachingColor blackColor(StdColors::Black());
DrawSurface *surface = window->GetDrawSurface();
surface->FillRect(licenseReaderTextRect, whiteColor);
int32_t ascent = rfont->GetMetrics().m_ascent;
const LicenseReaderLine *lines = *licenseReaderLines;
for (unsigned int i = 0; i < licenseReaderNumLines; i++)
{
int32_t lineY = licenseReaderTextRect.top + ascent + static_cast<int32_t>(kLicenseReaderTextSpacing * i);
lineY -= static_cast<int32_t>(licenseReaderTextScroll);
surface->DrawStringConstrained(Point::Create(licenseReaderTextRect.left, lineY), lines[i].m_text.ToShortStr(), licenseReaderTextRect, blackColor, rfont);
}
}
static void CycleLicenseReaderMouseHistory()
{
for (unsigned int ri = 1; ri < kLicenseReaderPointHistoryLength; ri++)
{
unsigned int i = kLicenseReaderPointHistoryLength - ri;
licenseReaderPointHistory[i] = licenseReaderPointHistory[i - 1];
}
}
static void HandleLicenseReaderScroll(Window *window, int32_t offset)
{
int32_t newScroll = static_cast<int32_t>(licenseReaderTextScroll) + offset;
if (newScroll < 0)
newScroll = 0;
else if (newScroll > static_cast<int32_t>(licenseReaderTextScrollMax))
newScroll = licenseReaderTextScrollMax;
if (newScroll != licenseReaderTextScroll)
{
licenseReaderTextScroll = newScroll;
licenseReaderScrollBarWidget->SetState(newScroll);
DrawLicenseReader(window);
}
}
static void AutoScrollLicenseReader(Window *window)
{
if (licenseReaderIsScrolling)
return;
int32_t decayRate = 2;
if (licenseReaderVelocity < 0)
{
HandleLicenseReaderScroll(window, licenseReaderVelocity);
licenseReaderVelocity += decayRate;
if (licenseReaderVelocity > 0)
licenseReaderVelocity = 0;
}
else if (licenseReaderVelocity > 0)
{
HandleLicenseReaderScroll(window, licenseReaderVelocity);
licenseReaderVelocity -= decayRate;
if (licenseReaderVelocity < 0)
licenseReaderVelocity = 0;
}
}
static void ComputeLicenseReaderVelocity()
{
int32_t velocity = licenseReaderPointHistory[kLicenseReaderPointHistoryLength - 1].v - licenseReaderPointHistory[0].v;
licenseReaderVelocity = velocity;
}
static void LicenseReaderScrollBarUpdate(void *captureContext, PortabilityLayer::Widget *widget, int part)
{
Window *window = static_cast<Window*>(captureContext); // This is stupid and very lazy...
const int incrementalStepping = kLicenseReaderTextSpacing;
const int pageStepping = 20;
switch (part)
{
case kControlUpButtonPart:
widget->SetState(widget->GetState() - incrementalStepping);
break;
case kControlDownButtonPart:
widget->SetState(widget->GetState() + incrementalStepping);
break;
case kControlPageUpPart:
widget->SetState(widget->GetState() - pageStepping * incrementalStepping);
break;
case kControlPageDownPart:
widget->SetState(widget->GetState() + pageStepping * incrementalStepping);
break;
default:
break;
};
licenseReaderTextScroll = widget->GetState();
DrawLicenseReader(window);
}
static int16_t LicenseReaderFilter(void *context, Dialog *dialog, const TimeTaggedVOSEvent *evt)
{
bool handledIt = false;
int16_t hit = -1;
if (!evt)
{
if (licenseReaderIsScrolling)
CycleLicenseReaderMouseHistory();
else
AutoScrollLicenseReader(dialog->GetWindow());
return -1;
}
Window *window = dialog->GetWindow();
DrawSurface *surface = window->GetDrawSurface();
if (evt->IsKeyDownEvent())
{
switch (PackVOSKeyCode(evt->m_vosEvent.m_event.m_keyboardInputEvent))
{
case PL_KEY_SPECIAL(kEnter):
case PL_KEY_NUMPAD_SPECIAL(kEnter):
dialog->GetItems()[kOkayButton - 1].GetWidget()->SetHighlightStyle(kControlButtonPart, true);
PLSysCalls::Sleep(8);
dialog->GetItems()[kOkayButton - 1].GetWidget()->SetHighlightStyle(kControlButtonPart, false);
hit = kOkayButton;
handledIt = true;
break;
default:
handledIt = false;
break;
}
}
if (evt->m_vosEvent.m_eventType == GpVOSEventTypes::kMouseInput)
{
const GpMouseInputEvent &mouseEvt = evt->m_vosEvent.m_event.m_mouseInputEvent;
Point mouseLocalPt = window->MouseToLocal(mouseEvt);
switch (mouseEvt.m_eventType)
{
case GpMouseEventTypes::kDown:
if (licenseReaderTextRect.Contains(mouseLocalPt))
{
for (unsigned int i = 0; i < kLicenseReaderPointHistoryLength; i++)
licenseReaderPointHistory[i] = mouseLocalPt;
licenseReaderIsScrolling = true;
}
else if (licenseReaderScrollBarWidget != nullptr && licenseReaderScrollBarWidget->GetRect().Contains(mouseLocalPt))
{
licenseReaderScrollBarWidget->Capture(dialog->GetWindow(), mouseLocalPt, LicenseReaderScrollBarUpdate);
licenseReaderTextScroll = licenseReaderScrollBarWidget->GetState();
DrawLicenseReader(dialog->GetWindow());
}
break;
case GpMouseEventTypes::kLeave:
case GpMouseEventTypes::kUp:
licenseReaderIsScrolling = false;
ComputeLicenseReaderVelocity();
break;
case GpMouseEventTypes::kMove:
if (licenseReaderIsScrolling)
{
Point prevPoint = licenseReaderPointHistory[0];
licenseReaderPointHistory[0] = mouseLocalPt;
HandleLicenseReaderScroll(window, prevPoint.v - mouseLocalPt.v);
}
break;
default:
break;
}
}
if (!handledIt)
return -1;
return hit;
}