Most remaining level editor work

This commit is contained in:
elasota
2020-03-01 17:01:35 -05:00
parent abd4f1a978
commit 7b27d6c6b5
48 changed files with 1211 additions and 945 deletions

View File

@@ -73,6 +73,7 @@
<Import Project="..\GpMainApp.props" />
<Import Project="..\FreeTypePublic.props" />
<Import Project="..\FreeTypeImport.props" />
<Import Project="..\Release.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
@@ -91,6 +92,7 @@
<Import Project="..\GpMainApp.props" />
<Import Project="..\FreeTypePublic.props" />
<Import Project="..\FreeTypeImport.props" />
<Import Project="..\Release.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />

View File

@@ -63,7 +63,11 @@ int GpMain::Run()
// This appears to be the "standard" Mac sample rate, probably rounded from 244800/11.
adProps.m_type = g_gpGlobalConfig.m_audioDriverType;
adProps.m_sampleRate = (244800 * 2 + 11) / (11 * 2);
#ifdef NDEBUG
adProps.m_debug = true;
#else
adProps.m_debug = false;
#endif
IGpInputDriver **inputDrivers = static_cast<IGpInputDriver**>(malloc(sizeof(IGpInputDriver*) * g_gpGlobalConfig.m_numInputDrivers));

View File

@@ -59,18 +59,28 @@ void ColorOval (DrawSurface *surface, const Rect &theRect, long color)
surface->SetForeColor(wasColor);
}
//-------------------------------------------------------------- ColorRegion
void ColorOvalMaskPattern(DrawSurface *surface, const Rect &theRect, long color, bool isMask, const uint8_t *pattern)
{
const PortabilityLayer::RGBAColor &rgbaColor = PortabilityLayer::StandardPalette::GetInstance()->GetColors()[color];
const PortabilityLayer::RGBAColor wasColor = surface->GetForeColor();
surface->SetForeColor(rgbaColor);
surface->FillEllipseWithPattern(theRect, isMask, pattern);
surface->SetForeColor(wasColor);
}
//-------------------------------------------------------------- ColorRegionMaskPattern
// Given a region and color index, this function draws a solid<69>
// region in that color. Current port, pen mode, etc. assumed.
void ColorRegion (DrawSurface *surface, PortabilityLayer::ScanlineMask *scanlineMask, long colorIndex)
void ColorRegionMaskPattern (DrawSurface *surface, PortabilityLayer::ScanlineMask *scanlineMask, long colorIndex, bool isMask, const uint8_t *pattern)
{
const PortabilityLayer::RGBAColor &rgbaColor = PortabilityLayer::StandardPalette::GetInstance()->GetColors()[colorIndex];
const PortabilityLayer::RGBAColor wasColor = surface->GetForeColor();
surface->SetForeColor(rgbaColor);
surface->FillScanlineMask(scanlineMask);
surface->FillScanlineMaskWithPattern(scanlineMask, isMask, pattern);
surface->SetForeColor(wasColor);
}

View File

@@ -124,18 +124,19 @@ void OpenCoordWindow (void)
Rect src, dest;
Point globalMouse;
short direction, dist;
PortabilityLayer::WindowManager *wm = PortabilityLayer::WindowManager::GetInstance();
if (coordWindow == nil)
{
const uint16_t windowStyle = PortabilityLayer::WindowStyleFlags::kTitleBar | PortabilityLayer::WindowStyleFlags::kMiniBar | PortabilityLayer::WindowStyleFlags::kCloseBox;
QSetRect(&coordWindowRect, 0, 0, 50, 38);
if (thisMac.hasColor)
coordWindow = NewCWindow(nil, &coordWindowRect,
PSTR("Tools"), false, windowStyle, kPutInFront, 0L);
else
coordWindow = NewWindow(nil, &coordWindowRect,
PSTR("Tools"), false, windowStyle, kPutInFront, 0L);
{
PortabilityLayer::WindowDef wdef = PortabilityLayer::WindowDef::Create(coordWindowRect, windowStyle, true, 0, 0, PSTR("Tools"));
coordWindow = wm->CreateWindow(wdef);
}
if (coordWindow == nil)
RedAlert(kErrNoMemory);
@@ -148,7 +149,7 @@ void OpenCoordWindow (void)
MoveWindow(coordWindow, isCoordH, isCoordV, true);
GetWindowRect(coordWindow, &dest);
BringToFront(coordWindow);
wm->PutWindowBehind(coordWindow, wm->GetPutInFrontSentinel());
PortabilityLayer::WindowManager::GetInstance()->ShowWindow(coordWindow);
// FlagWindowFloating(coordWindow); TEMP - use flaoting windows
HiliteAllWindows();

View File

@@ -374,8 +374,6 @@ void DrawDefaultButton (Dialog *theDialog)
surface->FrameRoundRect(offsetRect, 8, 8);
}
}
PenNormal();
}
//-------------------------------------------------------------- GetDialogString
@@ -602,7 +600,6 @@ void DrawDialogUserText (Dialog *dial, short item, StringPtr text, Boolean inver
iRect.right -= inset;
// Draw centered
PL_NotYetImplemented_TODO("Clip to iRect");
const int32_t ascender = surface->MeasureFontAscender();
@@ -709,7 +706,7 @@ void FrameOvalDialogItem (Dialog *theDialog, short item)
// Given a dialog item, this function draws any combination of 4 sides<65>
// of a box around it. Which sides get drawn is encoded in "sides".
void BorderDialogItem (Dialog *theDialog, short item, short sides)
void BorderDialogItem(Dialog *theDialog, short item, short sides, short thickness, const uint8_t *pattern)
{
// 1 = left
// 2 = top
@@ -725,29 +722,65 @@ void BorderDialogItem (Dialog *theDialog, short item, short sides)
if (sides >= 8) // 8 = right
{
const Point pointA = Point::Create(itemRect.right, itemRect.top);
const Point pointB = Point::Create(itemRect.right, itemRect.bottom);
surface->DrawLine(pointA, pointB);
const Point pointB = Point::Create(itemRect.right + thickness, itemRect.bottom + 1);
const Rect rect = Rect::Create(pointA.v, pointA.h, pointB.v, pointB.h);
if (pattern)
{
surface->SetForeColor(StdColors::White());
surface->FillRect(rect);
surface->SetForeColor(StdColors::Black());
surface->FillRectWithPattern8x8(rect, true, pattern);
}
else
surface->FillRect(rect);
sides -= 8;
}
if (sides >= 4) // 4 = bottom
{
const Point pointA = Point::Create(itemRect.left, itemRect.bottom);
const Point pointB = Point::Create(itemRect.right, itemRect.bottom);
surface->DrawLine(pointA, pointB);
const Point pointB = Point::Create(itemRect.right + 1, itemRect.bottom + thickness);
const Rect rect = Rect::Create(pointA.v, pointA.h, pointB.v, pointB.h);
if (pattern)
{
surface->SetForeColor(StdColors::White());
surface->FillRect(rect);
surface->SetForeColor(StdColors::Black());
surface->FillRectWithPattern8x8(rect, true, pattern);
}
else
surface->FillRect(rect);
sides -= 4;
}
if (sides >= 2) // 2 = top
{
const Point pointA = Point::Create(itemRect.left, itemRect.top - 1);
const Point pointB = Point::Create(itemRect.right, itemRect.top - 1);
surface->DrawLine(pointA, pointB);
const Point pointB = Point::Create(itemRect.right + 1, itemRect.top + thickness);
const Rect rect = Rect::Create(pointA.v, pointA.h, pointB.v, pointB.h);
if (pattern)
{
surface->SetForeColor(StdColors::White());
surface->FillRect(rect);
surface->SetForeColor(StdColors::Black());
surface->FillRectWithPattern8x8(rect, true, pattern);
}
else
surface->FillRect(rect);
sides -= 2;
}
if (sides >= 1) // 1 = left
{
const Point pointA = Point::Create(itemRect.left - 1, itemRect.top);
const Point pointB = Point::Create(itemRect.left - 1, itemRect.bottom);
surface->DrawLine(pointA, pointB);
const Point pointB = Point::Create(itemRect.left - 1 + thickness, itemRect.bottom + 1);
const Rect rect = Rect::Create(pointA.v, pointA.h, pointB.v, pointB.h);
if (pattern)
{
surface->SetForeColor(StdColors::White());
surface->FillRect(rect);
surface->SetForeColor(StdColors::Black());
surface->FillRectWithPattern8x8(rect, true, pattern);
}
else
surface->FillRect(rect);
}
}

View File

@@ -43,6 +43,6 @@ void LoadDialogPICT (Dialog *, short, short);
void FrameDialogItem (Dialog *, short);
void FrameDialogItemC (Dialog *, short, long);
void FrameOvalDialogItem (Dialog *, short);
void BorderDialogItem (Dialog *, short, short);
void BorderDialogItem (Dialog *theDialog, short item, short sides, short thickness, const uint8_t *pattern);
void ShadowDialogItem (Dialog *, short, short);
void EraseDialogItem (Dialog *, short);

View File

@@ -135,7 +135,8 @@ void BackSpinCursor (short);
void ColorText (DrawSurface *surface, const Point &, StringPtr, long); // --- ColorUtils.c
void ColorRect (DrawSurface *surface, const Rect &, long);
void ColorOval (DrawSurface *surface, const Rect &, long);
void ColorRegion (DrawSurface *surface, PortabilityLayer::ScanlineMask *scanlineMask, long colorIndex);
void ColorOvalMaskPattern (DrawSurface *surface, const Rect &, long, bool, const uint8_t *);
void ColorRegionMaskPattern (DrawSurface *surface, PortabilityLayer::ScanlineMask *scanlineMask, long colorIndex, bool isMask, const uint8_t *pattern);
void ColorLine (DrawSurface *surface, short, short, short, short, long);
void HiliteRect (DrawSurface *surface, const Rect &rect, short, short);
void ColorFrameRect (DrawSurface *surface, const Rect &theRect, long colorIndex);

View File

@@ -17,6 +17,7 @@
#include "FileManager.h"
#include "HostFileSystem.h"
#include "House.h"
#include "PLTimeTaggedVOSEvent.h"
#include "RectUtils.h"
#include "ResourceManager.h"
@@ -26,7 +27,7 @@
void UpdateGoToDialog (Dialog *);
Boolean GoToFilter (Dialog *, EventRecord *, short *);
int16_t GoToFilter (Dialog *dial, const TimeTaggedVOSEvent *evt);
extern PortabilityLayer::ResourceArchive *houseResFork;
@@ -594,7 +595,6 @@ void GenerateRetroLinks (void)
void UpdateGoToDialog (Dialog *theDialog)
{
DrawDialog(theDialog);
DrawDefaultButton(theDialog);
FrameDialogItemC(theDialog, 10, kRedOrangeColor8);
}
@@ -602,37 +602,27 @@ void UpdateGoToDialog (Dialog *theDialog)
//-------------------------------------------------------------- GoToFilter
// Dialog filter for the "Go To Room..." dialog.
Boolean GoToFilter (Dialog *dial, EventRecord *event, short *item)
int16_t GoToFilter(Dialog *dial, const TimeTaggedVOSEvent *evt)
{
switch (event->what)
if (!evt)
return -1;
if (evt->IsKeyDownEvent())
{
case keyDown:
switch (event->message)
const GpKeyboardInputEvent &keyEvt = evt->m_vosEvent.m_event.m_keyboardInputEvent;
switch (PackVOSKeyCode(keyEvt))
{
case PL_KEY_SPECIAL(kEnter):
case PL_KEY_NUMPAD_SPECIAL(kEnter):
case PL_KEY_SPECIAL(kEnter):
case PL_KEY_NUMPAD_SPECIAL(kEnter):
FlashDialogButton(dial, kOkayButton);
*item = kOkayButton;
return(true);
break;
default:
return(false);
}
break;
case updateEvt:
SetPortDialogPort(dial);
UpdateGoToDialog(dial);
EndUpdate(dial->GetWindow());
event->what = nullEvent;
return(false);
break;
return kOkayButton;
default:
return(false);
break;
return -1;
}
}
return -1;
}
//-------------------------------------------------------------- DoGoToDialog
@@ -664,10 +654,12 @@ Boolean GoToFilter (Dialog *dial, EventRecord *event, short *item)
leaving = false;
canceled = false;
UpdateGoToDialog(theDialog);
while (!leaving)
{
ModalDialog(GoToFilter, &item);
item = theDialog->ExecuteModal(GoToFilter);
if (item == kOkayButton)
{

View File

@@ -14,6 +14,7 @@
#include "DialogUtils.h"
#include "HostDisplayDriver.h"
#include "IGpDisplayDriver.h"
#include "PLTimeTaggedVOSEvent.h"
#define kHouseInfoDialogID 1001
@@ -31,7 +32,7 @@
long CountTotalHousePoints (void);
void UpdateHouseInfoDialog (Dialog *);
Boolean HouseFilter (Dialog *, EventRecord *, short *);
int16_t HouseFilter(Dialog *dial, const TimeTaggedVOSEvent *evt);
Boolean WarnLockingHouse (void);
void HowToZeroScores (void);
@@ -109,7 +110,6 @@ void UpdateHouseInfoDialog (Dialog *theDialog)
{
short nChars;
DrawDialog(theDialog);
nChars = GetDialogStringLen(theDialog, kBannerTextItem);
SetDialogNumToStr(theDialog, kBannerNCharsItem, (long)nChars);
nChars = GetDialogStringLen(theDialog, kTrailerTextItem);
@@ -121,7 +121,7 @@ void UpdateHouseInfoDialog (Dialog *theDialog)
//-------------------------------------------------------------- HouseFilter
Boolean HouseFilter (Dialog *dial, EventRecord *event, short *item)
int16_t HouseFilter(Dialog *dial, const TimeTaggedVOSEvent *evt)
{
Point mouseIs;
short nChars;
@@ -134,70 +134,66 @@ Boolean HouseFilter (Dialog *dial, EventRecord *event, short *item)
SetDialogNumToStr(dial, kTrailerNCharsItem, (long)nChars);
keyHit = false;
}
switch (event->what)
{
case keyDown:
switch (event->message)
{
case PL_KEY_SPECIAL(kEnter):
case PL_KEY_NUMPAD_SPECIAL(kEnter):
FlashDialogButton(dial, kOkayButton);
*item = kOkayButton;
return(true);
break;
case PL_KEY_SPECIAL(kEscape):
FlashDialogButton(dial, kCancelButton);
*item = kCancelButton;
return(true);
break;
default:
keyHit = true;
return(false);
}
break;
case mouseDown:
return(false);
break;
case mouseUp:
return(false);
break;
case updateEvt:
SetPortDialogPort(dial);
UpdateHouseInfoDialog(dial);
EndUpdate(dial->GetWindow());
event->what = nullEvent;
return(false);
break;
default:
mouseIs = event->where;
mouseIs -= dial->GetWindow()->TopLeftCoord();
if ((houseEditText1.Contains(mouseIs)) ||
(houseEditText2.Contains(mouseIs)))
if (evt)
{
if (evt->m_vosEvent.m_eventType == GpVOSEventTypes::kKeyboardInput)
{
if (houseCursorIs != kBeamCursor)
const GpKeyboardInputEvent &keyEvt = evt->m_vosEvent.m_event.m_keyboardInputEvent;
if (keyEvt.m_eventType == GpKeyboardInputEventTypes::kDown)
{
PortabilityLayer::HostDisplayDriver::GetInstance()->SetStandardCursor(EGpStandardCursors::kIBeam);
houseCursorIs = kBeamCursor;
switch (PackVOSKeyCode(keyEvt))
{
case PL_KEY_NUMPAD_SPECIAL(kEnter):
FlashDialogButton(dial, kOkayButton);
return kOkayButton;
case PL_KEY_SPECIAL(kEscape):
FlashDialogButton(dial, kCancelButton);
return kCancelButton;
default:
keyHit = true;
return -1;
}
}
else if (keyEvt.m_eventType == GpKeyboardInputEventTypes::kDownChar || keyEvt.m_eventType == GpKeyboardInputEventTypes::kAutoChar)
{
keyHit = true;
return -1;
}
}
else
else if (evt->m_vosEvent.m_eventType == GpVOSEventTypes::kMouseInput)
{
if (houseCursorIs != kArrowCursor)
const GpMouseInputEvent &mouseEvt = evt->m_vosEvent.m_event.m_mouseInputEvent;
if (mouseEvt.m_eventType == GpMouseEventTypes::kMove)
{
InitCursor();
houseCursorIs = kArrowCursor;
mouseIs = Point::Create(mouseEvt.m_x, mouseEvt.m_y);
mouseIs -= dial->GetWindow()->TopLeftCoord();
if ((houseEditText1.Contains(mouseIs)) ||
(houseEditText2.Contains(mouseIs)))
{
if (houseCursorIs != kBeamCursor)
{
PortabilityLayer::HostDisplayDriver::GetInstance()->SetStandardCursor(EGpStandardCursors::kIBeam);
houseCursorIs = kBeamCursor;
}
}
else
{
if (houseCursorIs != kArrowCursor)
{
InitCursor();
houseCursorIs = kArrowCursor;
}
}
}
}
return(false);
break;
}
return -1;
}
//-------------------------------------------------------------- DoHouseInfo
@@ -243,10 +239,12 @@ void DoHouseInfo (void)
GetDialogItemRect(houseInfoDialog, kTrailerTextItem, &houseEditText2);
houseCursorIs = kArrowCursor;
leaving = false;
UpdateHouseInfoDialog(houseInfoDialog);
while (!leaving)
{
ModalDialog(HouseFilter, &item);
item = houseInfoDialog->ExecuteModal(HouseFilter);
if (item == kOkayButton)
{

View File

@@ -66,9 +66,9 @@ void UpdateLinkControl (void)
switch (linkType)
{
case kSwitchLinkOnly:
case kSwitchLinkOnly:
if (objActive == kNoObjectSelected)
HiliteControl(linkControl, kControlInactive);
linkControl->SetEnabled(false);// HiliteControl(linkControl, kControlInactive);
else
switch (thisRoom->objects[objActive].what)
{
@@ -119,18 +119,18 @@ void UpdateLinkControl (void)
case kBall:
case kDrip:
case kFish:
HiliteControl(linkControl, kControlActive);
linkControl->SetEnabled(true);
break;
default:
HiliteControl(linkControl, kControlInactive);
linkControl->SetEnabled(false);
break;
}
break;
case kTriggerLinkOnly:
if (objActive == kNoObjectSelected)
HiliteControl(linkControl, kControlInactive);
linkControl->SetEnabled(false);
else
switch (thisRoom->objects[objActive].what)
{
@@ -147,7 +147,7 @@ void UpdateLinkControl (void)
case kDartRt:
case kDrip:
case kFish:
HiliteControl(linkControl, kControlActive);
linkControl->SetEnabled(true);
break;
case kLightSwitch:
@@ -157,18 +157,18 @@ void UpdateLinkControl (void)
case kKnifeSwitch:
case kInvisSwitch:
if (linkRoom == thisRoomNumber)
HiliteControl(linkControl, kControlActive);
linkControl->SetEnabled(true);
break;
default:
HiliteControl(linkControl, kControlInactive);
linkControl->SetEnabled(false);
break;
}
break;
case kTransportLinkOnly:
if (objActive == kNoObjectSelected)
HiliteControl(linkControl, kControlInactive);
linkControl->SetEnabled(false);
else
switch (thisRoom->objects[objActive].what)
{
@@ -185,11 +185,11 @@ void UpdateLinkControl (void)
case kCalendar:
case kBulletin:
case kCloud:
HiliteControl(linkControl, kControlActive);
linkControl->SetEnabled(true);
break;
default:
HiliteControl(linkControl, kControlInactive);
linkControl->SetEnabled(false);
break;
}
break;
@@ -218,23 +218,25 @@ void OpenLinkWindow (void)
#ifndef COMPILEDEMO
Rect src, dest;
Point globalMouse;
PortabilityLayer::WindowManager *wm = PortabilityLayer::WindowManager::GetInstance();
if (linkWindow == nil)
{
const uint16_t windowStyle = PortabilityLayer::WindowStyleFlags::kTitleBar | PortabilityLayer::WindowStyleFlags::kMiniBar | PortabilityLayer::WindowStyleFlags::kCloseBox;
QSetRect(&linkWindowRect, 0, 0, 129, 30);
if (thisMac.hasColor)
linkWindow = NewCWindow(nil, &linkWindowRect,
PSTR("Link"), false, windowStyle, kPutInFront, 0L);
else
linkWindow = NewWindow(nil, &linkWindowRect,
PSTR("Link"), false, windowStyle, kPutInFront, 0L);
{
PortabilityLayer::WindowDef wdef = PortabilityLayer::WindowDef::Create(linkWindowRect, windowStyle, true, 0, 0, PSTR("Link"));
linkWindow = wm->CreateWindow(wdef);
}
wm->PutWindowBehind(linkWindow, wm->GetPutInFrontSentinel());
MoveWindow(linkWindow, isLinkH, isLinkV, true);
GetWindowRect(linkWindow, &dest);
BringToFront(linkWindow);
PortabilityLayer::WindowManager::GetInstance()->ShowWindow(linkWindow);
// FlagWindowFloating(linkWindow); TEMP - use flaoting windows
HiliteAllWindows();
@@ -250,6 +252,8 @@ void OpenLinkWindow (void)
basicState.m_text.Set(6, "Unlink");
basicState.m_window = linkWindow;
unlinkControl = PortabilityLayer::ButtonWidget::Create(basicState);
linkWindow->DrawControls();
linkRoom = -1;
linkObject = 255;
@@ -265,7 +269,7 @@ void CloseLinkWindow (void)
{
#ifndef COMPILEDEMO
if (linkWindow != nil)
DisposeWindow(linkWindow);
PortabilityLayer::WindowManager::GetInstance()->DestroyWindow(linkWindow);
linkWindow = nil;
isLinkOpen = false;
@@ -380,7 +384,7 @@ void HandleLinkClick (Point wherePt)
part = FindControl(wherePt, linkWindow, &theControl);
if ((theControl != nil) && (part != 0))
{
part = TrackControl(theControl, wherePt, nil);
part = theControl->Capture(wherePt, nullptr);
if (part != 0)
{
if (theControl == linkControl)

View File

@@ -368,7 +368,8 @@ void UpdateEditWindowTitle (void)
}
else
PasStringConcat(newTitle, PSTR("House Locked"));
SetWTitle(mainWindow, newTitle);
PortabilityLayer::WindowManager::GetInstance()->SetWindowTitle(mainWindow, newTitle);
}
#endif

View File

@@ -254,7 +254,7 @@ void RedrawMapContents (void)
surface->SetForeColor(StdColors::Blue());
Pattern dummyPat;
surface->FillRectWithPattern8x8(aRoom, *GetQDGlobalsGray(&dummyPat));
surface->FillRectWithPattern8x8(aRoom, true, *GetQDGlobalsGray(&dummyPat));
}
}
}

View File

@@ -339,7 +339,6 @@ void DragMarqueeHandle (Window *window, DrawSurface *surface, Point start, short
}
surface->InvertFrameRect(theMarquee.bounds, pattern);
surface->InvertFillRect(theMarquee.handle, pattern);
PenNormal();
InitCursor();
}
@@ -401,7 +400,6 @@ void DragMarqueeCorner (Window *window, DrawSurface *surface, Point start, short
}
surface->InvertFrameRect(theMarquee.bounds, pattern);
surface->InvertFillRect(theMarquee.handle, pattern);
PenNormal();
InitCursor();
}

View File

@@ -161,15 +161,12 @@ void DrawTable (Rect *tableTop, short down)
-HalfRectTall(&tempRect) + kTableShadowTop + down);
QOffsetRect(&tempRect, kTableShadowOffset, -kTableShadowOffset);
backSrcMap->SetPattern8x8(*GetQDGlobalsGray(&dummyPattern));
backSrcMap->SetMaskMode(true);
GetQDGlobalsGray(&dummyPattern);
if (thisMac.isDepth == 4)
ColorOval(backSrcMap, tempRect, 15);
ColorOvalMaskPattern(backSrcMap, tempRect, 15, true, dummyPattern);
else
ColorOval(backSrcMap, tempRect, k8DkstGrayColor);
backSrcMap->ClearPattern();
backSrcMap->SetMaskMode(false);
ColorOvalMaskPattern(backSrcMap, tempRect, k8DkstGrayColor, true, dummyPattern);
InsetRect(tableTop, 0, 1);
ColorRect(backSrcMap, *tableTop, brownC);
@@ -280,14 +277,11 @@ void DrawShelf (Rect *shelfTop)
if (mask)
{
backSrcMap->SetPattern8x8(*GetQDGlobalsGray(&dummyPattern));
backSrcMap->SetMaskMode(true);
GetQDGlobalsGray(&dummyPattern);
if (thisMac.isDepth == 4)
ColorRegion(backSrcMap, mask, 15);
ColorRegionMaskPattern(backSrcMap, mask, 15, true, dummyPattern);
else
ColorRegion(backSrcMap, mask, k8DkstGrayColor);
backSrcMap->ClearPattern();
backSrcMap->SetMaskMode(false);
ColorRegionMaskPattern(backSrcMap, mask, k8DkstGrayColor, true, dummyPattern);
mask->Destroy();
}
@@ -371,14 +365,11 @@ void DrawCabinet (Rect *cabinet)
if (mask)
{
backSrcMap->SetPattern8x8(*GetQDGlobalsGray(&dummyPattern));
backSrcMap->SetMaskMode(true);
GetQDGlobalsGray(&dummyPattern);
if (thisMac.isDepth == 4)
ColorRegion(backSrcMap, mask, 15);
ColorRegionMaskPattern(backSrcMap, mask, 15, true, dummyPattern);
else
ColorRegion(backSrcMap, mask, dkGrayC);
backSrcMap->ClearPattern();
backSrcMap->SetMaskMode(false);
ColorRegionMaskPattern(backSrcMap, mask, dkGrayC, true, dummyPattern);
mask->Destroy();
}
@@ -511,14 +502,11 @@ void DrawCounter(Rect *counter)
if (mask)
{
backSrcMap->SetPattern8x8(*GetQDGlobalsGray(&dummyPattern));
backSrcMap->SetMaskMode(true);
GetQDGlobalsGray(&dummyPattern);
if (thisMac.isDepth == 4)
ColorRegion(backSrcMap, mask, 15);
ColorRegionMaskPattern(backSrcMap, mask, 15, true, dummyPattern);
else
ColorRegion(backSrcMap, mask, dkGrayC);
backSrcMap->ClearPattern();
backSrcMap->SetMaskMode(false);
ColorRegionMaskPattern(backSrcMap, mask, dkGrayC, true, dummyPattern);
mask->Destroy();
}
@@ -758,10 +746,8 @@ void DrawDeckTable (Rect *tableTop, short down)
QOffsetRect(&tempRect, 0,
-HalfRectTall(&tempRect) + kTableShadowTop + down);
QOffsetRect(&tempRect, kTableShadowOffset, -kTableShadowOffset);
PenPat(GetQDGlobalsGray(&dummyPattern));
PenMask(true);
ColorOval(backSrcMap, tempRect, dkGrayC);
PenNormal();
GetQDGlobalsGray(&dummyPattern);
ColorOvalMaskPattern(backSrcMap, tempRect, dkGrayC, true, dummyPattern);
InsetRect(tableTop, 0, 1);
ColorRect(backSrcMap, *tableTop, kGoldColor);

View File

@@ -148,49 +148,51 @@ void DragHandle (Window *window, DrawSurface *surface, Point where)
{
short hDelta, vDelta;
Boolean whoCares;
bool redrawMainWindow = false;
switch (thisRoom->objects[objActive].what)
{
case kFloorVent:
case kCeilingVent:
case kFloorBlower:
case kCeilingBlower:
case kSewerGrate:
case kTaper:
case kCandle:
case kStubby:
case kTiki:
case kBBQ:
case kGrecoVent:
case kSewerBlower:
case kFloorVent:
case kCeilingVent:
case kFloorBlower:
case kCeilingBlower:
case kSewerGrate:
case kTaper:
case kCandle:
case kStubby:
case kTiki:
case kBBQ:
case kGrecoVent:
case kSewerBlower:
vDelta = thisRoom->objects[objActive].data.a.distance;
DragMarqueeHandle(window, surface, where, &vDelta);
thisRoom->objects[objActive].data.a.distance = vDelta;
whoCares = KeepObjectLegal();
break;
case kLiftArea:
case kLiftArea:
hDelta = thisRoom->objects[objActive].data.a.distance;
vDelta = thisRoom->objects[objActive].data.a.tall * 2;
DragMarqueeCorner(window, surface, where, &hDelta, &vDelta, false);
thisRoom->objects[objActive].data.a.distance = hDelta;
thisRoom->objects[objActive].data.a.tall = vDelta / 2;
whoCares = KeepObjectLegal();
InvalWindowRect(mainWindow, &mainWindowRect);
redrawMainWindow = true;
GetThisRoomsObjRects();
ReadyBackground(thisRoom->background, thisRoom->tiles);
DrawThisRoomsObjects();
break;
case kLeftFan:
case kRightFan:
case kLeftFan:
case kRightFan:
hDelta = thisRoom->objects[objActive].data.a.distance;
DragMarqueeHandle(window, surface, where, &hDelta);
thisRoom->objects[objActive].data.a.distance = hDelta;
whoCares = KeepObjectLegal();
break;
case kInvisBlower:
case kInvisBlower:
if (((thisRoom->objects[objActive].data.a.vector & 0x0F) == 1) ||
((thisRoom->objects[objActive].data.a.vector & 0x0F) == 4))
{
@@ -207,23 +209,23 @@ void DragHandle (Window *window, DrawSurface *surface, Point where)
whoCares = KeepObjectLegal();
break;
case kTable:
case kShelf:
case kDeckTable:
case kTable:
case kShelf:
case kDeckTable:
hDelta = RectWide(&thisRoom->objects[objActive].data.b.bounds);
DragMarqueeHandle(window, surface, where, &hDelta);
thisRoom->objects[objActive].data.b.bounds.right =
thisRoom->objects[objActive].data.b.bounds.left + hDelta;
whoCares = KeepObjectLegal();
InvalWindowRect(mainWindow, &mainWindowRect);
redrawMainWindow = true;
GetThisRoomsObjRects();
ReadyBackground(thisRoom->background, thisRoom->tiles);
DrawThisRoomsObjects();
break;
case kCabinet:
case kInvisObstacle:
case kInvisBounce:
case kCabinet:
case kInvisObstacle:
case kInvisBounce:
hDelta = RectWide(&thisRoom->objects[objActive].data.b.bounds);
vDelta = RectTall(&thisRoom->objects[objActive].data.b.bounds);
DragMarqueeCorner(window, surface, where, &hDelta, &vDelta, false);
@@ -232,14 +234,14 @@ void DragHandle (Window *window, DrawSurface *surface, Point where)
thisRoom->objects[objActive].data.b.bounds.bottom =
thisRoom->objects[objActive].data.b.bounds.top + vDelta;
whoCares = KeepObjectLegal();
InvalWindowRect(mainWindow, &mainWindowRect);
redrawMainWindow = true;
GetThisRoomsObjRects();
ReadyBackground(thisRoom->background, thisRoom->tiles);
DrawThisRoomsObjects();
break;
case kCounter:
case kDresser:
case kCounter:
case kDresser:
hDelta = RectWide(&thisRoom->objects[objActive].data.b.bounds);
vDelta = RectTall(&thisRoom->objects[objActive].data.b.bounds);
DragMarqueeCorner(window, surface, where, &hDelta, &vDelta, true);
@@ -248,26 +250,26 @@ void DragHandle (Window *window, DrawSurface *surface, Point where)
thisRoom->objects[objActive].data.b.bounds.top =
thisRoom->objects[objActive].data.b.bounds.bottom - vDelta;
whoCares = KeepObjectLegal();
InvalWindowRect(mainWindow, &mainWindowRect);
redrawMainWindow = true;
GetThisRoomsObjRects();
ReadyBackground(thisRoom->background, thisRoom->tiles);
DrawThisRoomsObjects();
break;
case kGreaseRt:
case kGreaseLf:
case kSlider:
case kGreaseRt:
case kGreaseLf:
case kSlider:
hDelta = thisRoom->objects[objActive].data.c.length;
DragMarqueeHandle(window, surface, where, &hDelta);
thisRoom->objects[objActive].data.c.length = hDelta;
whoCares = KeepObjectLegal();
InvalWindowRect(mainWindow, &mainWindowRect);
redrawMainWindow = true;
GetThisRoomsObjRects();
ReadyBackground(thisRoom->background, thisRoom->tiles);
DrawThisRoomsObjects();
break;
case kInvisTrans:
case kInvisTrans:
hDelta = thisRoom->objects[objActive].data.d.wide;
vDelta = thisRoom->objects[objActive].data.d.tall;
DragMarqueeCorner(window, surface, where, &hDelta, &vDelta, false);
@@ -276,13 +278,13 @@ void DragHandle (Window *window, DrawSurface *surface, Point where)
thisRoom->objects[objActive].data.d.wide = (Byte)hDelta;
thisRoom->objects[objActive].data.d.tall = vDelta;
whoCares = KeepObjectLegal();
InvalWindowRect(mainWindow, &mainWindowRect);
redrawMainWindow = true;
GetThisRoomsObjRects();
ReadyBackground(thisRoom->background, thisRoom->tiles);
DrawThisRoomsObjects();
break;
case kDeluxeTrans:
case kDeluxeTrans:
hDelta = ((thisRoom->objects[objActive].data.d.tall & 0xFF00) >> 8) * 4;
vDelta = (thisRoom->objects[objActive].data.d.tall & 0x00FF) * 4;
DragMarqueeCorner(window, surface, where, &hDelta, &vDelta, false);
@@ -292,14 +294,14 @@ void DragHandle (Window *window, DrawSurface *surface, Point where)
vDelta = 32;
thisRoom->objects[objActive].data.d.tall = ((hDelta / 4) << 8) + (vDelta / 4);
whoCares = KeepObjectLegal();
InvalWindowRect(mainWindow, &mainWindowRect);
redrawMainWindow = true;
GetThisRoomsObjRects();
ReadyBackground(thisRoom->background, thisRoom->tiles);
DrawThisRoomsObjects();
break;
case kFlourescent:
case kTrackLight:
case kFlourescent:
case kTrackLight:
hDelta = thisRoom->objects[objActive].data.f.length;
DragMarqueeHandle(window, surface, where, &hDelta);
thisRoom->objects[objActive].data.f.length = hDelta;
@@ -310,16 +312,16 @@ void DragHandle (Window *window, DrawSurface *surface, Point where)
DrawThisRoomsObjects();
break;
case kToaster:
case kToaster:
vDelta = thisRoom->objects[objActive].data.g.height;
DragMarqueeHandle(window, surface, where, &vDelta);
thisRoom->objects[objActive].data.g.height = vDelta;
whoCares = KeepObjectLegal();
break;
case kBall:
case kDrip:
case kFish:
case kBall:
case kDrip:
case kFish:
vDelta = thisRoom->objects[objActive].data.h.length;
DragMarqueeHandle(window, surface, where, &vDelta);
thisRoom->objects[objActive].data.h.length = vDelta;
@@ -336,7 +338,7 @@ void DragHandle (Window *window, DrawSurface *surface, Point where)
thisRoom->objects[objActive].data.i.bounds.bottom =
thisRoom->objects[objActive].data.i.bounds.top + vDelta;
whoCares = KeepObjectLegal();
InvalWindowRect(mainWindow, &mainWindowRect);
redrawMainWindow = true;
GetThisRoomsObjRects();
ReadyBackground(thisRoom->background, thisRoom->tiles);
DrawThisRoomsObjects();
@@ -346,6 +348,9 @@ void DragHandle (Window *window, DrawSurface *surface, Point where)
fileDirty = true;
UpdateMenus(false);
if (redrawMainWindow)
UpdateMainWindow();
}
#endif
@@ -2304,9 +2309,7 @@ void DrawThisRoomsObjects (void)
{
if (GetNumberOfLights(thisRoomNumber) <= 0)
{
surface->SetMaskMode(true);
surface->FillRectWithPattern8x8(backSrcRect, *GetQDGlobalsGray(&dummyPattern));
surface->SetMaskMode(false);
surface->FillRectWithPattern8x8(backSrcRect, true, *GetQDGlobalsGray(&dummyPattern));
}
for (i = 0; i < kMaxRoomObs; i++)

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,7 @@
#include "HostDisplayDriver.h"
#include "IGpDisplayDriver.h"
#include "RectUtils.h"
#include "PLPopupMenuWidget.h"
#include "PLTimeTaggedVOSEvent.h"
#include "QDPixMap.h"
#include "ResourceCompiledRef.h"
@@ -49,7 +50,7 @@ int16_t RoomFilter (Dialog *dialog, const TimeTaggedVOSEvent *evt);
short ChooseOriginalArt (short);
void UpdateOriginalArt (Dialog *);
Boolean OriginalArtFilter (Dialog *, EventRecord *, short *);
int16_t OriginalArtFilter (Dialog *dialog, const TimeTaggedVOSEvent *evt);
Boolean PictIDExists (short);
short GetFirstPICT (void);
void BitchAboutPICTNotFound (void);
@@ -66,6 +67,8 @@ Boolean originalFloor;
extern IGpCursor *handCursor;
extern short lastBackground;
extern PortabilityLayer::ResourceArchive *houseResFork;
//============================================================== Functions
//-------------------------------------------------------------- UpdateRoomInfoDialog
@@ -323,7 +326,6 @@ void HiliteTileOver (DrawSurface *surface, Point mouseIs)
}
surface->SetForeColor(StdColors::Black());
PenNormal();
tileOver = -1;
}
@@ -417,56 +419,64 @@ int16_t RoomFilter(Dialog *dial, const TimeTaggedVOSEvent *evt)
//-------------------------------------------------------------- DoRoomInfo
void DoRoomInfo (void)
void DoRoomInfo(void)
{
#ifndef COMPILEDEMO
#define kBackgroundsMenuID 140
#define kBackgroundsMenuID 140
Dialog *roomInfoDialog;
MenuHandle backgroundsMenu;
Str255 floorStr, suiteStr, objectsStr, tempStr;
short item, i, newBack;
char wasState;
Boolean leaving, wasFirstRoom, forceDraw;
PLError_t theErr;
tileOver = -1;
cursorIs = kArrowCursor;
tempBack = thisRoom->background;
backgroundsMenu = GetMenu(kBackgroundsMenuID);
// SetMenuItemTextStyle(backgroundsMenu, kOriginalArtworkItem, italic);
if (HouseHasOriginalPicts())
EnableMenuItem(backgroundsMenu, kOriginalArtworkItem);
// SetMenuItemTextStyle(backgroundsMenu, kOriginalArtworkItem, italic);
NumToString(thisRoom->floor, floorStr);
NumToString(thisRoom->suite, suiteStr);
NumToString(thisRoom->numObjects, objectsStr);
DialogTextSubstitutions substitutions(floorStr, suiteStr, objectsStr);
theErr = CreateOffScreenGWorld(&tileSrcMap, &tileSrcRect, kPreferredPixelFormat);
// CreateOffScreenPixMap(&tileSrcRect, &tileSrcMap);
// SetPort((GrafPtr)tileSrcMap);
// CreateOffScreenPixMap(&tileSrcRect, &tileSrcMap);
// SetPort((GrafPtr)tileSrcMap);
if ((tempBack > kStars) && (!PictIDExists(tempBack)))
{
BitchAboutPICTNotFound();
tempBack = kSimpleRoom;
}
if ((tempBack == 2002) || (tempBack == 2011) ||
(tempBack == 2016) || (tempBack == 2017))
if ((tempBack == 2002) || (tempBack == 2011) ||
(tempBack == 2016) || (tempBack == 2017))
LoadScaledGraphicCustom(tileSrcMap, tempBack - 800, &tileSrcRect);
else
LoadScaledGraphicCustom(tileSrcMap, tempBack, &tileSrcRect);
for (i = 0; i < kNumTiles; i++)
tempTiles[i] = thisRoom->tiles[i];
// CenterDialog(kRoomInfoDialogID);
// CenterDialog(kRoomInfoDialogID);
roomInfoDialog = PortabilityLayer::DialogManager::GetInstance()->LoadDialog(kRoomInfoDialogID, kPutInFront, &substitutions);
if (roomInfoDialog == nil)
RedAlert(kErrDialogDidntLoad);
SetPort(&roomInfoDialog->GetWindow()->GetDrawSurface()->m_port);
// Fix this later. TEMP
// AddMenuToPopUp(roomInfoDialog, kRoomPopupItem, backgroundsMenu);
{
PortabilityLayer::WidgetBasicState state;
GetDialogItemRect(roomInfoDialog, kRoomPopupItem, &state.m_rect);
state.m_resID = kBackgroundsMenuID;
state.m_enabled = true;
PortabilityLayer::PopupMenuWidget *roomPopupWidget = PortabilityLayer::PopupMenuWidget::Create(state);
roomInfoDialog->ReplaceWidget(kRoomPopupItem - 1, roomPopupWidget);
if (HouseHasOriginalPicts())
EnableMenuItem(roomPopupWidget->GetMenu(), kOriginalArtworkItem);
}
if (tempBack >= kUserBackground)
SetPopUpMenuValue(roomInfoDialog, kRoomPopupItem, kOriginalArtworkItem);
else
@@ -495,6 +505,8 @@ void DoRoomInfo (void)
while (!leaving)
{
bool needRedraw = false;
item = roomInfoDialog->ExecuteModal(RoomFilter);
if (item == kOkayButton)
@@ -543,8 +555,7 @@ void DoRoomInfo (void)
{
tempBack = newBack;
LoadScaledGraphicCustom(tileSrcMap, tempBack, &tileSrcRect);
InvalWindowRect(roomInfoDialog->GetWindow(), &tileSrc);
InvalWindowRect(roomInfoDialog->GetWindow(), &tileDest);
needRedraw = true;
}
}
else
@@ -571,8 +582,7 @@ void DoRoomInfo (void)
LoadScaledGraphicCustom(tileSrcMap, tempBack - 800, &tileSrcRect);
else
LoadScaledGraphicCustom(tileSrcMap, tempBack, &tileSrcRect);
InvalWindowRect(roomInfoDialog->GetWindow(), &tileSrc);
InvalWindowRect(roomInfoDialog->GetWindow(), &tileDest);
needRedraw = true;
}
}
else if (item == kBoundsButton)
@@ -582,10 +592,12 @@ void DoRoomInfo (void)
{
tempBack = newBack;
LoadScaledGraphicCustom(tileSrcMap, tempBack, &tileSrcRect);
InvalWindowRect(roomInfoDialog->GetWindow(), &tileSrc);
InvalWindowRect(roomInfoDialog->GetWindow(), &tileDest);
needRedraw = true;
}
}
if (needRedraw)
UpdateRoomInfoDialog(roomInfoDialog);
}
InitCursor();
@@ -602,133 +614,83 @@ void DoRoomInfo (void)
#ifndef COMPILEDEMO
void UpdateOriginalArt (Dialog *theDialog)
{
Pattern dummyPattern;
Pattern grayPattern;
GetQDGlobalsGray(&grayPattern);
DrawDialog(theDialog);
DrawDefaultButton(theDialog);
PenSize(2, 1);
if (!originalLeftOpen)
BorderDialogItem(theDialog, 7, 8);
BorderDialogItem(theDialog, 7, 8, 2, nullptr);
else
{
PenPat(GetQDGlobalsGray(&dummyPattern));
BorderDialogItem(theDialog, 7, 8);
PenPat(GetQDGlobalsBlack(&dummyPattern));
}
BorderDialogItem(theDialog, 7, 8, 2, grayPattern);
PenSize(1, 2);
if (!originalTopOpen)
BorderDialogItem(theDialog, 8, 4);
BorderDialogItem(theDialog, 8, 4, 2, nullptr);
else
{
PenPat(GetQDGlobalsGray(&dummyPattern));
BorderDialogItem(theDialog, 8, 4);
PenPat(GetQDGlobalsBlack(&dummyPattern));
}
BorderDialogItem(theDialog, 8, 4, 2, grayPattern);
PenSize(2, 1);
if (!originalRightOpen)
BorderDialogItem(theDialog, 9, 1);
BorderDialogItem(theDialog, 9, 1, 2, nullptr);
else
{
PenPat(GetQDGlobalsGray(&dummyPattern));
BorderDialogItem(theDialog, 9, 1);
PenPat(GetQDGlobalsBlack(&dummyPattern));
}
BorderDialogItem(theDialog, 9, 1, 2, grayPattern);
PenSize(1, 2);
if (!originalBottomOpen)
BorderDialogItem(theDialog, 10, 2);
BorderDialogItem(theDialog, 10, 2, 2, nullptr);
else
{
PenPat(GetQDGlobalsGray(&dummyPattern));
BorderDialogItem(theDialog, 10, 2);
PenPat(GetQDGlobalsBlack(&dummyPattern));
}
PenSize(1, 1);
BorderDialogItem(theDialog, 10, 2, 2, grayPattern);
}
#endif
//-------------------------------------------------------------- OriginalArtFilter
#ifndef COMPILEDEMO
Boolean OriginalArtFilter (Dialog *dial, EventRecord *event, short *item)
int16_t OriginalArtFilter(Dialog *dial, const TimeTaggedVOSEvent *evt)
{
Point mouseIs;
switch (event->what)
if (!evt)
return -1;
if (evt->IsKeyDownEvent())
{
case keyDown:
switch (event->message)
switch (PackVOSKeyCode(evt->m_vosEvent.m_event.m_keyboardInputEvent))
{
case PL_KEY_SPECIAL(kEnter):
case PL_KEY_NUMPAD_SPECIAL(kEnter):
case PL_KEY_SPECIAL(kEnter):
case PL_KEY_NUMPAD_SPECIAL(kEnter):
FlashDialogButton(dial, kOkayButton);
*item = kOkayButton;
return(true);
break;
return kOkayButton;
case PL_KEY_SPECIAL(kEscape):
case PL_KEY_SPECIAL(kEscape):
FlashDialogButton(dial, kCancelButton);
*item = kCancelButton;
return(true);
break;
return kCancelButton;
case PL_KEY_SPECIAL(kTab):
case PL_KEY_SPECIAL(kTab):
SelectDialogItemText(dial, kPICTIDItem, 0, 1024);
return(true);
break;
default:
return(false);
return 0;
default:
return -1;
}
break;
case mouseDown:
mouseIs = event->where;
}
else if (evt->IsLMouseDownEvent())
{
const GpMouseInputEvent &mouseEvt = evt->m_vosEvent.m_event.m_mouseInputEvent;
mouseIs = Point::Create(mouseEvt.m_x, mouseEvt.m_y);
mouseIs -= dial->GetWindow()->TopLeftCoord();
if (leftBound.Contains(mouseIs))
{
*item = 7;
return(true);
}
return 7;
else if (topBound.Contains(mouseIs))
{
*item = 8;
return(true);
}
return 8;
else if (rightBound.Contains(mouseIs))
{
*item = 9;
return(true);
}
return 9;
else if (bottomBound.Contains(mouseIs))
{
*item = 10;
return(true);
}
return 10;
else
return(false);
break;
case mouseUp:
return(false);
break;
case updateEvt:
SetPortDialogPort(dial);
UpdateOriginalArt(dial);
EndUpdate(dial->GetWindow());
event->what = nullEvent;
return(false);
break;
default:
return(false);
break;
return -1;
}
return -1;
}
#endif
@@ -775,10 +737,12 @@ short ChooseOriginalArt (short was)
SetDialogItemValue(theDialog, kFloorSupportCheck, (short)originalFloor);
leaving = false;
UpdateOriginalArt(theDialog);
while (!leaving)
{
ModalDialog(OriginalArtFilter, &item);
item = theDialog->ExecuteModal(OriginalArtFilter);
if (item == kOkayButton)
{
@@ -903,18 +867,11 @@ short GetFirstPICT (void)
Handle resHandle;
Str255 resName;
PL_NotYetImplemented();
int16_t resID = 0;
if (!houseResFork->FindFirstResourceOfType('PICT', resID))
return -1;
//resHandle = Get1IndResource('PICT', 1);
resHandle = Handle();
if (resHandle != nil)
{
const PortabilityLayer::ResourceArchiveRef *resRef = PortabilityLayer::ResourceManager::GetInstance()->ResourceForHandle(resHandle.MMBlock());
resHandle.Dispose();
return resRef->m_resID;
}
else
return (-1);
return resID;
}
//-------------------------------------------------------------- BitchAboutPICTNotFound

View File

@@ -134,7 +134,6 @@ void FrameSelectedTool (DrawSurface *surface)
InsetRect(&theRect, 1, 1);
surface->FrameRect(theRect);
PenNormal();
ForeColor(blackColor);
}
#endif
@@ -484,6 +483,7 @@ void HandleToolsClick (Point wherePt)
{
EraseSelectedTool();
SwitchToolModes(newMode);
UpdateToolsWindow();
}
}
}

View File

@@ -91,6 +91,8 @@ namespace PortabilityLayer
int16_t ExecuteModal(DialogFilterFunc_t filterFunc) override;
bool ReplaceWidget(unsigned int itemIndex, Widget *widget) override;
bool Populate(DialogTemplate *tmpl, const DialogTextSubstitutions *substitutions);
void DrawControls(bool redraw);
@@ -390,6 +392,19 @@ namespace PortabilityLayer
}
}
bool DialogImpl::ReplaceWidget(unsigned int itemIndex, Widget *widget)
{
DialogItem &item = m_items[itemIndex];
Widget *oldWidget = item.GetWidget();
if (!m_window->ReplaceWidget(oldWidget, widget))
return false;
m_items[itemIndex].m_widget = widget;
return true;
}
bool DialogImpl::Populate(DialogTemplate *tmpl, const DialogTextSubstitutions *substitutions)
{
Window *window = this->GetWindow();

View File

@@ -9,6 +9,7 @@ struct TimeTaggedVOSEvent;
namespace PortabilityLayer
{
class DialogImpl;
class Widget;
class DialogManager
@@ -20,7 +21,7 @@ namespace PortabilityLayer
static DialogManager *GetInstance();
};
class DialogItem
class DialogItem final
{
public:
explicit DialogItem(Widget *widget);
@@ -29,6 +30,8 @@ namespace PortabilityLayer
Widget *GetWidget() const;
private:
friend class DialogImpl;
Widget *m_widget;
};
}

View File

@@ -90,7 +90,11 @@ struct Menu
bool haveMenuLayout;
size_t layoutWidth;
size_t layoutHeight;
size_t layoutBaseHeight;
size_t topItemsTruncated;
size_t bottomItemsTruncated;
size_t layoutFinalHeight;
PortabilityLayer::MMHandleBlock *stringBlobHandle;
@@ -143,6 +147,7 @@ namespace PortabilityLayer
bool FindMenuShortcut(uint16_t &menuID, uint16_t &itemID, uint8_t shortcutChar) override;
void MenuSelect(const Vec2i &initialPoint, int16_t *outMenu, uint16_t *outItem) override;
void PopupMenuSelect(const THandle<Menu> &menu, const Vec2i &popupMenuPos, const Vec2i &initialPoint, size_t initialItem, uint16_t *outItem) override;
void DrawMenuBar() override;
void SetMenuVisible(bool isVisible) override;
@@ -158,13 +163,17 @@ namespace PortabilityLayer
MenuSelectionState();
~MenuSelectionState();
void HandleSelectionOfMenu(MenuManagerImpl *mm, Menu **menuHdl, bool &outNeedRedraw);
void HandleSelectionOfMenu(MenuManagerImpl *mm, Menu **menuHdl, bool isPopup, size_t initialItem, bool &outNeedRedraw);
void Dismiss();
THandle<Menu> GetSelectedMenu() const;
DrawSurface *GetRenderedMenu() const;
const unsigned int *GetSelectedItem() const;
bool IsPopup() const;
const Vec2i &GetPopupPosition() const;
void SetPopupPosition(const Vec2i &popupPosition);
void SelectItem(size_t item);
void ClearSelection();
@@ -173,8 +182,10 @@ namespace PortabilityLayer
THandle<Menu> m_currentMenu;
DrawSurface *m_menuGraf;
Vec2i m_popupPosition;
unsigned int m_itemIndex;
bool m_haveItem;
bool m_isPopup;
};
void RefreshMenuBarLayout();
@@ -347,7 +358,10 @@ namespace PortabilityLayer
menu->prevMenu = nullptr;
menu->nextMenu = nullptr;
menu->layoutWidth = 0;
menu->layoutHeight = 0;
menu->layoutBaseHeight = 0;
menu->layoutFinalHeight = 0;
menu->bottomItemsTruncated = 0;
menu->topItemsTruncated = 0;
return THandle<Menu>(menuData);
}
@@ -664,6 +678,56 @@ namespace PortabilityLayer
this->DrawMenuBar();
}
void MenuManagerImpl::PopupMenuSelect(const THandle<Menu> &menuHdl, const Vec2i &popupMenuPos, const Vec2i &initialPoint, size_t initialItem, uint16_t *outItem)
{
THandle<Menu> menuHdlCopy = menuHdl; // Hack
bool needRedraw = false;
m_menuSelectionState.SetPopupPosition(popupMenuPos);
m_menuSelectionState.HandleSelectionOfMenu(this, menuHdlCopy, true, initialItem, needRedraw);
ProcessMouseMoveTo(initialPoint);
TimeTaggedVOSEvent evt;
bool canDismiss = false;
while (!canDismiss)
{
if (WaitForEvent(&evt, 1))
{
if (evt.m_vosEvent.m_eventType == GpVOSEventTypes::kMouseInput)
{
switch (evt.m_vosEvent.m_event.m_mouseInputEvent.m_eventType)
{
case GpMouseEventTypes::kMove:
ProcessMouseMoveTo(PortabilityLayer::Vec2i(evt.m_vosEvent.m_event.m_mouseInputEvent.m_x, evt.m_vosEvent.m_event.m_mouseInputEvent.m_y));
break;
case GpMouseEventTypes::kDown:
if (evt.m_vosEvent.m_event.m_mouseInputEvent.m_button == GpMouseButtons::kLeft)
ProcessMouseMoveTo(PortabilityLayer::Vec2i(evt.m_vosEvent.m_event.m_mouseInputEvent.m_x, evt.m_vosEvent.m_event.m_mouseInputEvent.m_y));
break;
case GpMouseEventTypes::kUp:
if (evt.m_vosEvent.m_event.m_mouseInputEvent.m_button == GpMouseButtons::kLeft)
canDismiss = true;
break;
}
}
}
}
if (outItem)
*outItem = 0;
Menu *menu = *menuHdl;
if (const unsigned int *selectedItem = m_menuSelectionState.GetSelectedItem())
{
if (outItem)
*outItem = (*selectedItem) + 1;
}
m_menuSelectionState.Dismiss();
}
void MenuManagerImpl::DrawMenuBar()
{
if (!m_haveIcon)
@@ -893,9 +957,21 @@ namespace PortabilityLayer
Menu *selectedMenu = *m_menuSelectionState.GetSelectedMenu();
const PixMap *pixMap = *renderedMenu->m_port.GetPixMap();
const size_t xCoordinate = kMenuBarInitialPadding + selectedMenu->menuIndex * kMenuBarItemPadding * 2 + selectedMenu->cumulativeOffset - kMenuBarItemPadding;
int32_t xCoordinate = 0;
int32_t yCoordinate = 0;
if (!m_menuSelectionState.IsPopup())
{
xCoordinate = kMenuBarInitialPadding + selectedMenu->menuIndex * kMenuBarItemPadding * 2 + selectedMenu->cumulativeOffset - kMenuBarItemPadding;
yCoordinate = kMenuBarHeight;
}
else
{
const Vec2i popupPosition = m_menuSelectionState.GetPopupPosition();
xCoordinate = popupPosition.m_x;
yCoordinate = popupPosition.m_y;
}
displayDriver->DrawSurface(renderedMenu->m_ddSurface, xCoordinate, kMenuBarHeight, pixMap->m_rect.right, pixMap->m_rect.bottom);
displayDriver->DrawSurface(renderedMenu->m_ddSurface, xCoordinate, yCoordinate, pixMap->m_rect.right, pixMap->m_rect.bottom);
}
}
@@ -987,7 +1063,8 @@ namespace PortabilityLayer
menu->haveMenuLayout = true;
menu->layoutWidth = width;
menu->layoutHeight = cumulativeHeight;
menu->layoutBaseHeight = cumulativeHeight;
menu->layoutFinalHeight = menu->layoutBaseHeight;
}
void MenuManagerImpl::ProcessMouseMoveTo(const Vec2i &point)
@@ -995,7 +1072,7 @@ namespace PortabilityLayer
if (point.m_y < 0)
return;
if (point.m_y < static_cast<int>(kMenuBarHeight))
if (!m_menuSelectionState.IsPopup() && point.m_y < static_cast<int>(kMenuBarHeight))
{
m_menuSelectionState.ClearSelection();
ProcessMouseMoveToMenuBar(point);
@@ -1034,7 +1111,7 @@ namespace PortabilityLayer
if (selectedMenu)
{
bool needRedraw = false;
m_menuSelectionState.HandleSelectionOfMenu(this, menuHdl, needRedraw);
m_menuSelectionState.HandleSelectionOfMenu(this, menuHdl, false, 0, needRedraw);
if (needRedraw)
DrawMenuBar();
@@ -1048,11 +1125,24 @@ namespace PortabilityLayer
if (selectedMenuHandle)
{
Menu *menu = *selectedMenuHandle;
const int32_t xCoordinate = static_cast<int32_t>(kMenuBarInitialPadding + menu->menuIndex * kMenuBarItemPadding * 2 + menu->cumulativeOffset - kMenuBarItemPadding);
int32_t xCoordinate = 0;
int32_t yCoordinate = 0;
const Vec2i localPoint = point - Vec2i(xCoordinate, kMenuBarHeight);
if (!m_menuSelectionState.IsPopup())
{
xCoordinate = static_cast<int32_t>(kMenuBarInitialPadding + menu->menuIndex * kMenuBarItemPadding * 2 + menu->cumulativeOffset - kMenuBarItemPadding);
yCoordinate = kMenuBarHeight;
}
else
{
const Vec2i popupPos = m_menuSelectionState.GetPopupPosition();
xCoordinate = popupPos.m_x;
yCoordinate = popupPos.m_y;
}
if (localPoint.m_x < 0 || localPoint.m_y < 0 || static_cast<size_t>(localPoint.m_x) >= menu->layoutWidth || static_cast<size_t>(localPoint.m_y) >= menu->layoutHeight)
const Vec2i localPoint = point - Vec2i(xCoordinate, yCoordinate);
if (localPoint.m_x < 0 || localPoint.m_y < 0 || static_cast<size_t>(localPoint.m_x) >= menu->layoutWidth || static_cast<size_t>(localPoint.m_y) >= menu->layoutFinalHeight)
{
m_menuSelectionState.ClearSelection();
return;
@@ -1098,6 +1188,7 @@ namespace PortabilityLayer
MenuManagerImpl::MenuSelectionState::MenuSelectionState()
: m_menuGraf(nullptr)
, m_haveItem(false)
, m_isPopup(false)
, m_itemIndex(0)
{
}
@@ -1107,7 +1198,7 @@ namespace PortabilityLayer
Dismiss();
}
void MenuManagerImpl::MenuSelectionState::HandleSelectionOfMenu(MenuManagerImpl *mm, Menu **menuHdl, bool &outNeedRedraw)
void MenuManagerImpl::MenuSelectionState::HandleSelectionOfMenu(MenuManagerImpl *mm, Menu **menuHdl, bool isPopup, size_t initialItem, bool &outNeedRedraw)
{
outNeedRedraw = false;
@@ -1117,14 +1208,24 @@ namespace PortabilityLayer
if (menuHdl != m_currentMenu)
{
Dismiss();
m_currentMenu = menuHdl;
m_isPopup = isPopup;
Menu *menu = *menuHdl;
outNeedRedraw = true;
int32_t yCoordinate = isPopup ? m_popupPosition.m_y : kMenuBarHeight;
mm->RefreshMenuLayout(menu);
if (m_isPopup)
{
assert(initialItem < menu->numMenuItems);
m_popupPosition.m_y -= static_cast<int32_t>(menu->menuItems[initialItem].layoutYOffset);
}
RenderMenu(menu);
}
}
@@ -1139,6 +1240,7 @@ namespace PortabilityLayer
m_currentMenu = nullptr;
m_haveItem = false;
m_isPopup = false;
}
THandle<Menu> MenuManagerImpl::MenuSelectionState::GetSelectedMenu() const
@@ -1159,6 +1261,21 @@ namespace PortabilityLayer
return &m_itemIndex;
}
bool MenuManagerImpl::MenuSelectionState::IsPopup() const
{
return m_isPopup;
}
const Vec2i &MenuManagerImpl::MenuSelectionState::GetPopupPosition() const
{
return m_popupPosition;
}
void MenuManagerImpl::MenuSelectionState::SetPopupPosition(const Vec2i &popupPosition)
{
m_popupPosition = popupPosition;
}
void MenuManagerImpl::MenuSelectionState::SelectItem(size_t item)
{
if (m_haveItem && m_itemIndex == item)
@@ -1186,7 +1303,7 @@ namespace PortabilityLayer
{
PortabilityLayer::QDManager *qdManager = PortabilityLayer::QDManager::GetInstance();
const Rect menuRect = Rect::Create(0, 0, static_cast<int16_t>(menu->layoutHeight), static_cast<int16_t>(menu->layoutWidth));
const Rect menuRect = Rect::Create(0, 0, static_cast<int16_t>(menu->layoutFinalHeight), static_cast<int16_t>(menu->layoutWidth));
if (m_menuGraf == nullptr)
{
@@ -1208,16 +1325,16 @@ namespace PortabilityLayer
qdState->SetForeColor(gs_barMidColor);
{
const Rect rect = Rect::Create(0, 0, menu->layoutHeight, menu->layoutWidth);
const Rect rect = Rect::Create(0, 0, menu->layoutFinalHeight, menu->layoutWidth);
surface->FillRect(rect);
surface->SetForeColor(StdColors::White());
surface->FillRect(Rect::Create(0, 0, 1, menu->layoutWidth - 1));
surface->FillRect(Rect::Create(1, 0, menu->layoutHeight - 1, 1));
surface->FillRect(Rect::Create(1, 0, menu->layoutFinalHeight - 1, 1));
surface->SetForeColor(RGBAColor::Create(kDarkGray, kDarkGray, kDarkGray, 255));
surface->FillRect(Rect::Create(1, menu->layoutWidth - 1, menu->layoutHeight, menu->layoutWidth));
surface->FillRect(Rect::Create(menu->layoutHeight - 1, 1, menu->layoutHeight, menu->layoutWidth - 1));
surface->FillRect(Rect::Create(1, menu->layoutWidth - 1, menu->layoutFinalHeight, menu->layoutWidth));
surface->FillRect(Rect::Create(menu->layoutFinalHeight - 1, 1, menu->layoutFinalHeight, menu->layoutWidth - 1));
}
m_menuGraf->SetSystemFont(kMenuFontSize, PortabilityLayer::FontFamilyFlag_Bold);

View File

@@ -43,6 +43,7 @@ namespace PortabilityLayer
virtual bool FindMenuShortcut(uint16_t &menuID, uint16_t &itemID, uint8_t shortcutChar) = 0;
virtual void MenuSelect(const Vec2i &initialPoint, int16_t *outMenu, uint16_t *outItem) = 0;
virtual void PopupMenuSelect(const THandle<Menu> &menu, const Vec2i &popupMenuPos, const Vec2i &initialPoint, size_t initialItem, uint16_t *outItem) = 0;
virtual void DrawMenuBar() = 0;
virtual void SetMenuVisible(bool isVisible) = 0;

View File

@@ -52,6 +52,31 @@ namespace PortabilityLayer
return WidgetHandleStates::kIgnored;
}
void ButtonWidget::OnEnabledChanged()
{
DrawControl(m_window->GetDrawSurface());
}
int16_t ButtonWidget::Capture(const Point &pos, WidgetUpdateCallback_t callback)
{
for (;;)
{
TimeTaggedVOSEvent evt;
if (WaitForEvent(&evt, 1))
{
if (evt.IsLMouseUpEvent())
{
const Point pt = m_window->MouseToLocal(evt.m_vosEvent.m_event.m_mouseInputEvent);
if (m_rect.Contains(pt))
return RegionIDs::kContent;
else
return RegionIDs::kNone;
}
}
}
}
bool ButtonWidget::Init(const WidgetBasicState &state)
{
(void)state;
@@ -60,7 +85,14 @@ namespace PortabilityLayer
void ButtonWidget::DrawControl(DrawSurface *surface)
{
surface->SetForeColor(StdColors::Black());
surface->SetForeColor(StdColors::White());
surface->FillRect(this->m_rect.Inset(1, 1));
if (m_enabled)
surface->SetForeColor(StdColors::Black());
else
surface->SetForeColor(RGBAColor::Create(136, 136, 136, 255));
surface->FrameRect(this->m_rect);
surface->SetSystemFont(12, PortabilityLayer::FontFamilyFlag_Bold);
int32_t x = (m_rect.left + m_rect.right - static_cast<int32_t>(surface->MeasureString(m_text.ToShortStr()))) / 2;

View File

@@ -16,6 +16,10 @@ namespace PortabilityLayer
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt) override;
void OnEnabledChanged() override;
int16_t Capture(const Point &pos, WidgetUpdateCallback_t callback) override;
private:
bool m_haveMouseDown;
PascalStr<255> m_text;

View File

@@ -136,11 +136,6 @@ void HiliteWindow(WindowPtr window, bool highlighted)
PL_NotYetImplemented();
}
void DisposeWindow(WindowPtr window)
{
PL_NotYetImplemented();
}
void GetWindowBounds(WindowPtr window, WindowRegionType windowRegion, Rect *rect)
{
if (windowRegion == kWindowContentRgn)
@@ -204,11 +199,6 @@ void ShowWindow(WindowPtr window)
PortabilityLayer::WindowManager::GetInstance()->ShowWindow(window);
}
void SetWTitle(WindowPtr window, const PLPasStr &title)
{
PL_NotYetImplemented_TODO("Editor");
}
long MenuSelect(Point point)
{
int16_t menuID = 0;
@@ -760,6 +750,29 @@ PortabilityLayer::Widget* Window::GetWidgetById() const
return nullptr;
}
bool Window::ReplaceWidget(PortabilityLayer::Widget *oldWidget, PortabilityLayer::Widget *newWidget)
{
for (size_t i = 0; i < m_numWidgets; i++)
{
if (m_widgets[i] == oldWidget)
{
assert(newWidget->GetWindow() == nullptr);
oldWidget->Destroy();
m_widgets[i] = newWidget;
newWidget->m_window = this;
newWidget->DrawControl(&m_surface);
m_surface.m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
return true;
}
}
return false;
}
void Window::FocusWidget(PortabilityLayer::Widget *widget)
{
if (m_widgetWithFocus != widget)

View File

@@ -100,7 +100,8 @@ struct Window
bool AddWidget(PortabilityLayer::Widget *widget);
ArrayView<PortabilityLayer::Widget*> GetWidgets() const;
PortabilityLayer::Widget* GetWidgetById() const;
PortabilityLayer::Widget *GetWidgetById() const;
bool ReplaceWidget(PortabilityLayer::Widget *oldWidget, PortabilityLayer::Widget *newWidget);
void FocusWidget(PortabilityLayer::Widget *widget);
PortabilityLayer::Widget *GetWidgetWithFocus() const;
@@ -257,7 +258,6 @@ bool TrackGoAway(WindowPtr window, Point point); // Returns true if the close bo
Int32 GrowWindow(WindowPtr window, Point start, Rect *size);
bool TrackBox(WindowPtr window, Point point, int part); // Returns true if grow/shrink box was clicked (part corresponds to type)
void HiliteWindow(WindowPtr window, bool highlighted);
void DisposeWindow(WindowPtr window);
void GetWindowBounds(WindowPtr window, WindowRegionType windowRegion, Rect *rect);
WindowPtr GetNewCWindow(int resID, void *storage, WindowPtr behind);
@@ -266,7 +266,6 @@ WindowPtr NewWindow(void *storage, const Rect *bounds, const PLPasStr &title, Bo
void SizeWindow(WindowPtr window, int width, int height, Boolean addToUpdateRegion);
void MoveWindow(WindowPtr window, int x, int y, Boolean moveToFront);
void ShowWindow(WindowPtr window);
void SetWTitle(WindowPtr window, const PLPasStr &title);
long MenuSelect(Point point); // Breaks into menu select routine (in practice we'll just forward one from the queue?)

View File

@@ -4,6 +4,7 @@
#include "PLArrayView.h"
#include "PLPasStr.h"
#include "PLEditboxWidget.h"
#include "PLStandardColors.h"
DialogTextSubstitutions::DialogTextSubstitutions()
@@ -109,5 +110,14 @@ void ShowDialogItem(Dialog *dialog, int item)
void HideDialogItem(Dialog *dialog, int item)
{
dialog->GetItems()[item - 1].GetWidget()->SetVisible(false);
PortabilityLayer::Widget *widget = dialog->GetItems()[item - 1].GetWidget();
if (widget->IsVisible())
{
widget->SetVisible(false);
DrawSurface *surface = dialog->GetWindow()->GetDrawSurface();
surface->SetForeColor(StdColors::White());
surface->FillRect(widget->GetExpandedRect());
}
}

View File

@@ -40,6 +40,8 @@ struct Dialog
virtual void SetItemVisibility(unsigned int itemIndex, bool isVisible) = 0;
virtual int16_t ExecuteModal(DialogFilterFunc_t filterFunc) = 0;
virtual bool ReplaceWidget(unsigned int itemIndex, PortabilityLayer::Widget *widget) = 0;
};
typedef Boolean(*ModalFilterUPP)(Dialog *dial, EventRecord *event, short *item);

View File

@@ -46,6 +46,9 @@ namespace PortabilityLayer
void EditboxWidget::EditboxWidget::DrawControl(DrawSurface *surface)
{
if (!m_visible)
return;
const Rect textRect = m_rect;
const Rect innerRect = textRect.Inset(-2, -2);
const Rect outerRect = innerRect.Inset(-1, -1);
@@ -224,6 +227,11 @@ namespace PortabilityLayer
return WidgetHandleStates::kIgnored;
}
Rect EditboxWidget::GetExpandedRect() const
{
return GetRect().Inset(-3, -3);
}
void EditboxWidget::Redraw()
{
if (m_window)

View File

@@ -22,6 +22,8 @@ namespace PortabilityLayer
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt) override;
Rect GetExpandedRect() const override;
bool HandlesTickEvents() const;
void SetSelection(size_t startChar, size_t endChar);

View File

@@ -4,7 +4,9 @@
#include "PLMenus.h"
#include "PLPasStr.h"
#include "PLStandardColors.h"
#include "PLTimeTaggedVOSEvent.h"
#include "FontFamily.h"
#include "Vec2i.h"
namespace PortabilityLayer
{
@@ -13,17 +15,59 @@ namespace PortabilityLayer
{
}
PopupMenuWidget::~PopupMenuWidget()
{
if (m_menu)
m_menu.Dispose();
}
bool PopupMenuWidget::Init(const WidgetBasicState &state)
{
m_menu = GetMenu(state.m_resID);
m_menu = ::GetMenu(state.m_resID);
if (!m_menu)
return false;
return true;
}
//WidgetHandleState_t PopupMenuWidget::ProcessEvent(const TimeTaggedVOSEvent &evt);
//int16_t PopupMenuWidget::Capture(const Point &pos, WidgetUpdateCallback_t callback);
WidgetHandleState_t PopupMenuWidget::ProcessEvent(const TimeTaggedVOSEvent &evt)
{
if (evt.IsLMouseDownEvent())
{
const GpMouseInputEvent &mouseEvent = evt.m_vosEvent.m_event.m_mouseInputEvent;
const Vec2i globalPoint = Vec2i(mouseEvent.m_x, mouseEvent.m_y);
const Vec2i localPoint = globalPoint - Vec2i(m_window->m_wmX, m_window->m_wmY);
if (this->m_rect.Contains(Point::Create(localPoint.m_x, localPoint.m_y)))
{
int16_t part = Capture(Point::Create(localPoint.m_x, localPoint.m_y), nullptr);
if (part >= 1)
return WidgetHandleStates::kActivated;
else
return WidgetHandleStates::kIgnored;
}
}
return WidgetHandleStates::kIgnored;
}
int16_t PopupMenuWidget::Capture(const Point &pos, WidgetUpdateCallback_t callback)
{
MenuManager *mm = PortabilityLayer::MenuManager::GetInstance();
const Vec2i popupMenuPos = Vec2i(m_window->m_wmX, m_window->m_wmY) + Vec2i(m_rect.left, m_rect.top);
const Vec2i globalPos = Vec2i(pos.h, pos.v) + Vec2i(m_window->m_wmX, m_window->m_wmY);
uint16_t item = 0;
mm->PopupMenuSelect(m_menu, popupMenuPos, globalPos, m_state - 1, &item);
if (item < 1)
return -1;
this->SetState(item);
return item;
}
void PopupMenuWidget::DrawControl(DrawSurface *surface)
{
const Rect rect = m_rect;
@@ -59,9 +103,22 @@ namespace PortabilityLayer
}
}
void PopupMenuWidget::OnStateChanged()
{
DrawControl(m_window->GetDrawSurface());
}
PLPasStr PopupMenuWidget::GetString() const
{
if (m_state < 1)
return PSTR("");
const Menu *menu = (*m_menu);
return PortabilityLayer::MenuManager::GetInstance()->GetItemText(m_menu, m_state - 1);
}
const THandle<Menu> &PopupMenuWidget::GetMenu() const
{
return m_menu;
}
}

View File

@@ -14,12 +14,19 @@ namespace PortabilityLayer
bool Init(const WidgetBasicState &state) override;
//WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt);
//int16_t Capture(const Point &pos, WidgetUpdateCallback_t callback);
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt);
int16_t Capture(const Point &pos, WidgetUpdateCallback_t callback);
void DrawControl(DrawSurface *surface) override;
void OnStateChanged() override;
PLPasStr GetString() const override;
const THandle<Menu> &GetMenu() const;
protected:
~PopupMenuWidget();
private:
THandle<Menu> m_menu;
};

View File

@@ -3,6 +3,7 @@
#include "QDState.h"
#include "BitmapImage.h"
#include "DisplayDeviceManager.h"
#include "EllipsePlotter.h"
#include "FontFamily.h"
#include "FontManager.h"
#include "LinePlotter.h"
@@ -927,22 +928,6 @@ void DrawSurface::DrawPicture(THandle<BitmapImage> pictHdl, const Rect &bounds)
m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
}
void DrawSurface::SetPattern8x8(const uint8_t *pattern)
{
m_port.GetState()->SetPenPattern8x8(pattern);
}
void DrawSurface::ClearPattern()
{
m_port.GetState()->SetPenPattern8x8(nullptr);
}
void DrawSurface::SetMaskMode(bool maskMode)
{
m_port.GetState()->m_penMask = maskMode;
}
Rect DrawSurface::GetClipRect() const
{
return m_port.GetState()->m_clipRect;
@@ -1001,7 +986,7 @@ void DrawSurface::FillRect(const Rect &rect)
m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
}
void DrawSurface::FillRectWithPattern8x8(const Rect &rect, const uint8_t *pattern)
void DrawSurface::FillRectWithPattern8x8(const Rect &rect, bool isMask, const uint8_t *pattern)
{
if (!rect.IsValid())
return;
@@ -1037,6 +1022,10 @@ void DrawSurface::FillRectWithPattern8x8(const Rect &rect, const uint8_t *patter
case GpPixelFormats::k8BitStandard:
{
const uint8_t color = qdState->ResolveForeColor8(nullptr, 0);
uint8_t backColor = 0;
if (!isMask)
backColor = qdState->ResolveBackColor8(nullptr, 0);
size_t scanlineIndex = 0;
for (size_t ln = 0; ln < numLines; ln++)
@@ -1049,6 +1038,8 @@ void DrawSurface::FillRectWithPattern8x8(const Rect &rect, const uint8_t *patter
const int patternCol = static_cast<int>((patternFirstCol + col) & 7);
if ((pattern[patternRow] >> patternCol) & 1)
pixData[firstLineIndex + col] = color;
else if (!isMask)
pixData[firstLineIndex + col] = backColor;
}
}
}
@@ -1106,9 +1097,90 @@ void DrawSurface::FillEllipse(const Rect &rect)
}
}
void DrawSurface::FillEllipseWithPattern(const Rect &rect, bool isMask, const uint8_t *pattern)
{
if (!rect.IsValid() || rect.Width() < 1 || rect.Height() < 1)
return;
if (rect.Width() <= 2 || rect.Height() <= 2)
{
FillRectWithPattern8x8(rect, isMask, pattern);
return;
}
PortabilityLayer::ScanlineMask *mask = PortabilityLayer::ScanlineMaskConverter::CompileEllipse(PortabilityLayer::Rect2i(rect.top, rect.left, rect.bottom, rect.right));
if (mask)
{
FillScanlineMaskWithPattern(mask, isMask, pattern);
mask->Destroy();
}
}
void DrawSurface::FrameEllipse(const Rect &rect)
{
PL_NotYetImplemented();
if (!rect.IsValid())
return;
if (rect.Width() <= 2 || rect.Height() <= 2)
{
FillRect(rect);
return;
}
Rect constrainedRect = rect;
PortabilityLayer::QDPort *qdPort = &m_port;
const Rect portRect = qdPort->GetRect();
PortabilityLayer::QDState *qdState = qdPort->GetState();
constrainedRect = constrainedRect.Intersect(qdState->m_clipRect);
constrainedRect = constrainedRect.Intersect(portRect);
if (!constrainedRect.IsValid())
return;
GpPixelFormat_t pixelFormat = qdPort->GetPixelFormat();
PortabilityLayer::PixMapImpl *pixMap = static_cast<PortabilityLayer::PixMapImpl*>(*qdPort->GetPixMap());
const size_t pitch = pixMap->GetPitch();
const size_t firstIndex = static_cast<size_t>(constrainedRect.top) * pitch + static_cast<size_t>(constrainedRect.left);
const size_t numLines = static_cast<size_t>(constrainedRect.bottom - constrainedRect.top);
const size_t numCols = static_cast<size_t>(constrainedRect.right - constrainedRect.left);
uint8_t *pixData = static_cast<uint8_t*>(pixMap->GetPixelData());
PortabilityLayer::EllipsePlotter plotter;
plotter.Reset(PortabilityLayer::Rect2i(rect.top, rect.left, rect.bottom, rect.right));
PortabilityLayer::Rect2i constraintRect32 = PortabilityLayer::Rect2i(constrainedRect.top, constrainedRect.left, constrainedRect.bottom, constrainedRect.right);
switch (pixelFormat)
{
case GpPixelFormats::k8BitStandard:
{
const uint8_t color = qdState->ResolveForeColor8(nullptr, 0);
for (;;)
{
const PortabilityLayer::Vec2i pt = plotter.GetPoint();
if (constraintRect32.Contains(pt))
{
const size_t pixelIndex = static_cast<size_t>(pt.m_y - portRect.top) * pitch + static_cast<size_t>(pt.m_x - portRect.left);
pixData[pixelIndex] = color;
}
if (plotter.PlotNext() == PortabilityLayer::PlotDirection_Exhausted)
break;
}
}
break;
default:
PL_NotYetImplemented();
return;
}
m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
}
static void FillScanlineSpan(uint8_t *rowStart, size_t startCol, size_t endCol, uint8_t patternByte, uint8_t foreColor, uint8_t bgColor, bool mask)
@@ -1142,6 +1214,11 @@ static void FillScanlineSpan(uint8_t *rowStart, size_t startCol, size_t endCol,
}
void DrawSurface::FillScanlineMask(const PortabilityLayer::ScanlineMask *scanlineMask)
{
FillScanlineMaskWithPattern(scanlineMask, false, nullptr);
}
void DrawSurface::FillScanlineMaskWithPattern(const PortabilityLayer::ScanlineMask *scanlineMask, bool isMask, const uint8_t *pattern)
{
if (!scanlineMask)
return;
@@ -1175,7 +1252,6 @@ void DrawSurface::FillScanlineMask(const PortabilityLayer::ScanlineMask *scanlin
uint8_t foreColor8 = 0;
uint8_t backColor8 = 0;
const bool isMask = qdState->m_penMask;
const GpPixelFormat_t pixelFormat = pixMap->m_pixelFormat;
@@ -1193,9 +1269,9 @@ void DrawSurface::FillScanlineMask(const PortabilityLayer::ScanlineMask *scanlin
uint8_t pattern8x8[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
bool havePattern = false;
if (const uint8_t *statePattern = qdState->GetPattern8x8())
if (pattern)
{
memcpy(pattern8x8, statePattern, 8);
memcpy(pattern8x8, pattern, 8);
for (int i = 0; i < 8; i++)
{
if (pattern8x8[i] != 0xff)
@@ -1452,36 +1528,11 @@ const PortabilityLayer::RGBAColor &DrawSurface::GetBackColor() const
return m_port.GetState()->GetBackColor();
}
void PenInvertMode(bool invertMode)
{
PortabilityLayer::QDState *qdState = PortabilityLayer::QDManager::GetInstance()->GetState();
qdState->m_penInvert = invertMode;
}
void PenMask(bool maskMode)
{
PortabilityLayer::QDState *qdState = PortabilityLayer::QDManager::GetInstance()->GetState();
qdState->m_penMask = maskMode;
}
void PenPat(const Pattern *pattern)
{
PortabilityLayer::QDState *qdState = PortabilityLayer::QDManager::GetInstance()->GetState();
qdState->SetPenPattern8x8(*pattern);
}
void PenSize(int w, int h)
{
PL_NotYetImplemented();
}
void PenNormal()
{
PortabilityLayer::QDState *qdState = PortabilityLayer::QDManager::GetInstance()->GetState();
qdState->m_penInvert = false;
qdState->m_penMask = false;
}
void InsetRect(Rect *rect, int x, int y)
{
rect->left += x;

View File

@@ -112,11 +112,7 @@ void GetForeColor(RGBColor *color);
void ClipRect(const Rect *rect);
void GetClip(Rect *rect);
void PenInvertMode(bool invertMode);
void PenMask(bool maskMode);
void PenPat(const Pattern *pattern);
void PenSize(int w, int h);
void PenNormal();
void InsetRect(Rect *rect, int x, int y);
Pattern *GetQDGlobalsGray(Pattern *pattern);
Pattern *GetQDGlobalsBlack(Pattern *pattern);

View File

@@ -32,6 +32,8 @@ namespace ResourceValidationRules
};
}
static const char *kPICTExtension = ".bmp";
typedef ResourceValidationRules::ResourceValidationRule ResourceValidationRule_t;
namespace
@@ -302,6 +304,82 @@ namespace PortabilityLayer
return m_zipFileProxy->HasPrefix(resPrefix);
}
bool ResourceArchive::FindFirstResourceOfType(const ResTypeID &resTypeID, int16_t &outID) const
{
char resPrefix[6];
resTypeID.ExportAsChars(resPrefix);
resPrefix[4] = '/';
resPrefix[5] = '\0';
size_t fileIndex = 0;
if (!m_zipFileProxy->FindFirstWithPrefix(resPrefix, fileIndex))
return false;
const char *resName = nullptr;
size_t fnLength = 0;
m_zipFileProxy->GetFileName(fileIndex, resName, fnLength);
assert(fnLength > 5);
const char *idChars = resName + 5;
size_t idCharsRemaining = fnLength - 5;
const size_t extLength = strlen(kPICTExtension);
if (idCharsRemaining <= extLength)
return false;
if (memcmp(idChars + idCharsRemaining - extLength, kPICTExtension, extLength))
return false;
idCharsRemaining -= extLength;
bool isNegative = false;
if (idChars[0] == '-')
{
isNegative = true;
idCharsRemaining--;
idChars++;
}
if (idCharsRemaining == 0)
return false;
if (idChars[0] == '0' && (idCharsRemaining > 1 || isNegative))
return false;
int32_t resID = 0;
while (idCharsRemaining)
{
const char idChar = *idChars;
if (idChar < '0' || idChar > '9')
return false;
resID = resID * 10;
if (isNegative)
{
resID -= (idChar - '0');
if (resID < -32768)
return false;
}
else
{
resID += (idChar - '0');
if (resID > 32767)
return false;
}
idChars++;
idCharsRemaining--;
}
outID = static_cast<int16_t>(resID);
return true;
}
bool ResourceArchive::IndexResource(const ResTypeID &resTypeID, int id, size_t &outIndex, int &outValidationRule) const
{
const char *extension = ".bin";
@@ -314,7 +392,7 @@ namespace PortabilityLayer
}
else if (resTypeID == ResTypeID('Date') || resTypeID == ResTypeID('PICT'))
{
extension = ".bmp";
extension = kPICTExtension;
outValidationRule = ResourceValidationRules::kBMP;
}
else if (resTypeID == ResTypeID('STR#'))

View File

@@ -25,3 +25,8 @@ PortabilityLayer::RGBAColor StdColors::Blue()
{
return PortabilityLayer::RGBAColor::Create(0, 0, 255, 255);
}
PortabilityLayer::RGBAColor StdColors::Magenta()
{
return PortabilityLayer::RGBAColor::Create(255, 0, 255, 255);
}

View File

@@ -13,4 +13,5 @@ public:
static PortabilityLayer::RGBAColor Red();
static PortabilityLayer::RGBAColor Green();
static PortabilityLayer::RGBAColor Blue();
static PortabilityLayer::RGBAColor Magenta();
};

View File

@@ -94,6 +94,11 @@ namespace PortabilityLayer
return false;
}
Rect Widget::GetExpandedRect() const
{
return GetRect();
}
void Widget::GainFocus()
{
}

View File

@@ -72,6 +72,7 @@ namespace PortabilityLayer
virtual void SetHighlightStyle(int16_t style);
virtual bool HandlesTickEvents() const;
virtual Rect GetExpandedRect() const;
const Rect &GetRect() const;
Window *GetWindow() const;
@@ -118,7 +119,7 @@ namespace PortabilityLayer
void Destroy() override
{
static_cast<T*>(this)->~T();
this->~WidgetSpec();
Widget::BaseRelease(static_cast<T*>(this));
}
@@ -141,7 +142,7 @@ namespace PortabilityLayer
return nullptr;
}
if (!static_cast<Window*>(state.m_window)->AddWidget(widget))
if (state.m_window != nullptr && !static_cast<Window*>(state.m_window)->AddWidget(widget))
{
widget->Destroy();
return nullptr;

View File

@@ -59,16 +59,18 @@ struct DrawSurface final
void PushToDDSurface(IGpDisplayDriver *displayDriver);
void FillRect(const Rect &rect);
void FillRectWithPattern8x8(const Rect &rect, const uint8_t *pattern);
void FillRectWithPattern8x8(const Rect &rect, bool isMask, const uint8_t *pattern);
void FrameRect(const Rect &rect);
void FrameRoundRect(const Rect &rect, int quadrantWidth, int quadrantHeight);
void InvertFrameRect(const Rect &rect, const uint8_t *pattern);
void InvertFillRect(const Rect &rect, const uint8_t *pattern);
void FillEllipse(const Rect &rect);
void FillEllipseWithPattern(const Rect &rect, bool isMask, const uint8_t *pattern);
void FrameEllipse(const Rect &rect);
void FillScanlineMask(const PortabilityLayer::ScanlineMask *scanlineMask);
void FillScanlineMaskWithPattern(const PortabilityLayer::ScanlineMask *scanlineMask, bool isMask, const uint8_t *pattern);
void DrawLine(const Point &a, const Point &b);
@@ -90,11 +92,6 @@ struct DrawSurface final
void DrawPicture(THandle<BitmapImage> pictHandle, const Rect &rect);
void SetPattern8x8(const uint8_t *pattern);
void ClearPattern();
void SetMaskMode(bool maskMode);
Rect GetClipRect() const;
void SetClipRect(const Rect &rect);

View File

@@ -18,16 +18,11 @@ namespace PortabilityLayer
, m_isForeResolved8(false)
, m_isBackResolved8(false)
, m_clipRect(Rect::Create(INT16_MIN, INT16_MIN, INT16_MAX, INT16_MAX))
, m_penInvert(false)
, m_penMask(false)
, m_havePattern8x8(false)
{
m_backUnresolvedColor.r = m_backUnresolvedColor.g = m_backUnresolvedColor.b = m_backUnresolvedColor.a = 255;
m_foreUnresolvedColor.r = m_foreUnresolvedColor.g = m_foreUnresolvedColor.b = 0;
m_foreUnresolvedColor.a = 255;
m_penPos.h = m_penPos.v = 0;
memset(m_pattern8x8, 0, sizeof(m_pattern8x8));
}
void QDState::SetForeColor(const RGBAColor &color)
@@ -84,39 +79,4 @@ namespace PortabilityLayer
return resolvedColor;
}
}
void QDState::SetPenPattern8x8(const uint8_t *pattern)
{
if (!pattern)
{
m_havePattern8x8 = false;
return;
}
bool isSolid = true;
for (int i = 0; i < 8; i++)
{
if (pattern[i] != 0xff)
{
isSolid = false;
break;
}
}
if (isSolid)
m_havePattern8x8 = false;
else
{
m_havePattern8x8 = true;
memcpy(m_pattern8x8, pattern, sizeof(m_pattern8x8));
}
}
const uint8_t *QDState::GetPattern8x8() const
{
if (m_havePattern8x8)
return m_pattern8x8;
return nullptr;
}
}

View File

@@ -16,8 +16,6 @@ namespace PortabilityLayer
int m_fontSize;
Rect m_clipRect;
Point m_penPos;
bool m_penInvert;
bool m_penMask;
void SetForeColor(const RGBAColor &color);
void SetBackColor(const RGBAColor &color);
@@ -28,9 +26,6 @@ namespace PortabilityLayer
uint8_t ResolveForeColor8(const RGBAColor *palette, unsigned int numColors);
uint8_t ResolveBackColor8(const RGBAColor *palette, unsigned int numColors);
void SetPenPattern8x8(const uint8_t *pattern);
const uint8_t *GetPattern8x8() const;
private:
static uint8_t ResolveColor8(const RGBAColor &color, uint8_t &cached, bool &isCached, const RGBAColor *palette, unsigned int numColors);
@@ -42,9 +37,6 @@ namespace PortabilityLayer
uint8_t m_foreResolvedColor8;
uint8_t m_backResolvedColor8;
uint8_t m_pattern8x8[8];
bool m_havePattern8x8;
bool m_isForeResolved16;
bool m_isForeResolved8;
bool m_isBackResolved16;

View File

@@ -40,7 +40,8 @@ namespace PortabilityLayer
void SetRight(int32_t i);
bool IsValid() const;
Rect2i Intersect(const Rect2i &other) const;
Rect2i Intersect(const Rect2i &other) const;
bool Contains(const Vec2i &pt) const;
Rect ToShortRect() const;
};
@@ -156,6 +157,11 @@ namespace PortabilityLayer
const int32_t right = std::min(m_bottomRight.m_x, other.m_bottomRight.m_x);
return Rect2i(top, left, bottom, right);
}
inline bool Rect2i::Contains(const Vec2i &pt) const
{
return pt.m_x >= m_topLeft.m_x && pt.m_x < m_bottomRight.m_x && pt.m_y >= m_topLeft.m_y && pt.m_y < m_bottomRight.m_y;
}
inline Rect Rect2i::ToShortRect() const

View File

@@ -34,6 +34,7 @@ namespace PortabilityLayer
bool GetResourceSize(const ResTypeID &resTypeID, int id, size_t &outSize) const;
bool HasAnyResourcesOfType(const ResTypeID &resTypeID) const;
bool FindFirstResourceOfType(const ResTypeID &resTypeID, int16_t &outID) const;
private:
ResourceArchive(ZipFileProxy *zipFileProxy, IOStream *stream, ResourceArchiveRef *resourceHandles);

View File

@@ -97,6 +97,8 @@ namespace PortabilityLayer
bool IsBorderless() const;
uint16_t GetStyleFlags() const;
void SetTitle(const PLPasStr &str);
const PascalStr<255> &GetTitle() const;
private:
@@ -124,6 +126,7 @@ namespace PortabilityLayer
void FindWindow(const Point &point, Window **outWindow, short *outRegion) const override;
void DestroyWindow(Window *window) override;
void DragWindow(Window *window, const Point &startPoint, const Rect &constraintRect) override;
void SetWindowTitle(Window *window, const PLPasStr &title) override;
void RenderFrame(IGpDisplayDriver *displayDriver) override;
@@ -582,6 +585,12 @@ namespace PortabilityLayer
return m_styleFlags;
}
void WindowImpl::SetTitle(const PLPasStr &str)
{
m_title.Set(str.Length(), str.Chars());
m_chromeTheme->RenderChrome(this, m_chromeSurfaces + WindowChromeSides::kTop, WindowChromeSides::kTop);
}
const PascalStr<255> &WindowImpl::GetTitle() const
{
return m_title;
@@ -770,6 +779,11 @@ namespace PortabilityLayer
}
}
void WindowManagerImpl::SetWindowTitle(Window *window, const PLPasStr &title)
{
static_cast<WindowImpl*>(window)->SetTitle(title);
}
void WindowManagerImpl::RenderFrame(IGpDisplayDriver *displayDriver)
{
PortabilityLayer::DisplayDeviceManager *dd = PortabilityLayer::DisplayDeviceManager::GetInstance();

View File

@@ -5,6 +5,7 @@ struct DrawSurface;
struct GDevice;
struct IGpDisplayDriver;
struct Point;
class PLPasStr;
struct Rect;
struct Window;
@@ -25,6 +26,7 @@ namespace PortabilityLayer
virtual void FindWindow(const Point &point, Window **outWindow, short *outRegion) const = 0;
virtual void DestroyWindow(Window *window) = 0;
virtual void DragWindow(Window *window, const Point &startPoint, const Rect &constraintRect) = 0;
virtual void SetWindowTitle(Window *window, const PLPasStr &title) = 0;
virtual void RenderFrame(IGpDisplayDriver *displayDriver) = 0;

View File

@@ -137,21 +137,21 @@ namespace PortabilityLayer
// -1 = path precedes item, 1 = path succeeds item
if (delta < 0)
{
lastFileExclusive = midFile;
midFile = (firstFile + lastFileExclusive) / 2;
}
else if (delta > 0)
{
const bool isPathPrefix = ((itemNameLength > prefixLen) && !memcmp(prefix, itemPath, prefixLen));
if (isPathPrefix)
return true;
else
{
firstFile = midFile + 1;
lastFileExclusive = midFile;
midFile = (firstFile + lastFileExclusive) / 2;
}
}
else if (delta > 0)
{
firstFile = midFile + 1;
midFile = (firstFile + lastFileExclusive) / 2;
}
else //if(delta == 0)
{
// Found the directory
@@ -163,6 +163,40 @@ namespace PortabilityLayer
return false;
}
bool ZipFileProxy::FindFirstWithPrefix(const char *prefix, size_t &outFileIndex) const
{
size_t prefixLen = strlen(prefix);
// Could do binary search, but it's much more complicated in this case, just do linear scan...
for (size_t i = 0; i < m_numFiles; i++)
{
const UnalignedPtr<PortabilityLayer::ZipCentralDirectoryFileHeader> itemPtr = m_sortedFiles[i];
const PortabilityLayer::ZipCentralDirectoryFileHeader item = itemPtr.Get();
const uint16_t itemNameLength = item.m_fileNameLength;
const char *itemPath = GetZipItemName(itemPtr);
const int delta = ZipDirectorySearchPredicateResolved(prefix, itemPath, itemNameLength);
if (delta == 0)
continue;
if (delta < 0)
{
const bool isPathPrefix = ((itemNameLength > prefixLen) && !memcmp(prefix, itemPath, prefixLen));
if (isPathPrefix)
{
outFileIndex = i;
return true;
}
else
return false;
}
}
return false;
}
bool ZipFileProxy::LoadFile(size_t index, void *outBuffer)
{
ZipCentralDirectoryFileHeader centralDirHeader = m_sortedFiles[index].Get();
@@ -203,6 +237,15 @@ namespace PortabilityLayer
return m_sortedFiles[index].Get().m_uncompressedSize;
}
void ZipFileProxy::GetFileName(size_t index, const char *&outName, size_t &outLength) const
{
const UnalignedPtr<PortabilityLayer::ZipCentralDirectoryFileHeader> itemPtr = m_sortedFiles[index];
const PortabilityLayer::ZipCentralDirectoryFileHeader item = itemPtr.Get();
outLength = item.m_fileNameLength;
outName = GetZipItemName(itemPtr);
}
ZipFileProxy *ZipFileProxy::Create(IOStream *stream)
{
MemoryManager *mm = MemoryManager::GetInstance();

View File

@@ -16,9 +16,12 @@ namespace PortabilityLayer
bool LoadFile(size_t index, void *outBuffer);
bool HasPrefix(const char *path) const;
bool FindFirstWithPrefix(const char *resPrefix, size_t &outFileIndex) const;
size_t NumFiles() const;
size_t GetFileSize(size_t index) const;
void GetFileName(size_t index, const char *&outName, size_t &outLength) const;
static ZipFileProxy *Create(IOStream *stream);