Redo file prompts with in-game UI

This commit is contained in:
elasota
2020-09-12 22:29:57 -04:00
parent 8518d01c70
commit b23bb93506
44 changed files with 1133 additions and 362 deletions

View File

@@ -88,7 +88,7 @@ namespace PortabilityLayer
ArrayView<const DialogItem> GetItems() const override;
void SetItemVisibility(unsigned int itemIndex, bool isVisible) override;
int16_t ExecuteModal(DialogFilterFunc_t filterFunc) override;
int16_t ExecuteModal(void *captureContext, DialogFilterFunc_t filterFunc) override;
bool ReplaceWidget(unsigned int itemIndex, Widget *widget) override;
@@ -106,7 +106,7 @@ namespace PortabilityLayer
static void MakeStringSubstitutions(uint8_t *outStr, const uint8_t *inStr, const DialogTextSubstitutions *substitutions);
int16_t ExecuteModalInDarkenStack(DialogFilterFunc_t filterFunc);
int16_t ExecuteModalInDarkenStack(void *captureContext, DialogFilterFunc_t filterFunc);
Window *m_window;
DialogItem *m_items;
@@ -334,20 +334,20 @@ namespace PortabilityLayer
}
}
int16_t DialogImpl::ExecuteModal(DialogFilterFunc_t filterFunc)
int16_t DialogImpl::ExecuteModal(void *captureContext, DialogFilterFunc_t filterFunc)
{
Window *exclWindow = this->GetWindow();
WindowManager::GetInstance()->SwapExclusiveWindow(exclWindow);
int16_t result = ExecuteModalInDarkenStack(filterFunc);
int16_t result = ExecuteModalInDarkenStack(captureContext, filterFunc);
WindowManager::GetInstance()->SwapExclusiveWindow(exclWindow);
return result;
}
int16_t DialogImpl::ExecuteModalInDarkenStack(DialogFilterFunc_t filterFunc)
int16_t DialogImpl::ExecuteModalInDarkenStack(void *captureContext, DialogFilterFunc_t filterFunc)
{
Window *window = this->GetWindow();
Widget *capturingWidget = nullptr;
@@ -362,7 +362,7 @@ namespace PortabilityLayer
if (window->IsHandlingTickEvents())
window->OnTick();
const int16_t selection = filterFunc(this, haveEvent ? &evt : nullptr);
const int16_t selection = (filterFunc != nullptr) ? filterFunc(captureContext, this, haveEvent ? &evt : nullptr) : -1;
if (selection >= 0)
return selection;
@@ -371,7 +371,7 @@ namespace PortabilityLayer
{
if (capturingWidget != nullptr)
{
const WidgetHandleState_t state = capturingWidget->ProcessEvent(evt);
const WidgetHandleState_t state = capturingWidget->ProcessEvent(captureContext, evt);
if (state != WidgetHandleStates::kDigested)
capturingWidget = nullptr;
@@ -398,7 +398,7 @@ namespace PortabilityLayer
{
Widget *widget = this->m_items[i].GetWidget();
const WidgetHandleState_t state = widget->ProcessEvent(evt);
const WidgetHandleState_t state = widget->ProcessEvent(captureContext, evt);
if (state == WidgetHandleStates::kActivated)
return static_cast<int16_t>(i + 1);
@@ -621,7 +621,7 @@ namespace PortabilityLayer
private:
static int16_t AlertFilter(Dialog *dialog, const TimeTaggedVOSEvent *evt);
static int16_t AlertFilter(void *context, Dialog *dialog, const TimeTaggedVOSEvent *evt);
static DialogManagerImpl ms_instance;
};
@@ -706,7 +706,7 @@ namespace PortabilityLayer
return dialog;
}
int16_t DialogManagerImpl::AlertFilter(Dialog *dialog, const TimeTaggedVOSEvent *evt)
int16_t DialogManagerImpl::AlertFilter(void *context, Dialog *dialog, const TimeTaggedVOSEvent *evt)
{
return -1;
}
@@ -767,7 +767,7 @@ namespace PortabilityLayer
if (!dialog)
return 0;
int16_t hit = dialog->ExecuteModal(DialogManagerImpl::AlertFilter);
int16_t hit = dialog->ExecuteModal(nullptr, DialogManagerImpl::AlertFilter);
dialog->Destroy();
return hit;

View File

@@ -0,0 +1,680 @@
#include "FileBrowserUI.h"
#include "DialogManager.h"
#include "PLButtonWidget.h"
#include "FileManager.h"
#include "FontFamily.h"
#include "GpApplicationName.h"
#include "GpBuildVersion.h"
#include "GpRenderedFontMetrics.h"
#include "HostFileSystem.h"
#include "HostDirectoryCursor.h"
#include "HostSystemServices.h"
#include "IGpFont.h"
#include "WindowManager.h"
#include "MemoryManager.h"
#include "PLStandardColors.h"
#include "RenderedFont.h"
#include "ResolveCachingColor.h"
#include "WindowDef.h"
#include "MacRomanConversion.h"
#include "PLArrayView.h"
#include "PLControlDefinitions.h"
#include "PLCore.h"
#include "PLDialogs.h"
#include "PLEditboxWidget.h"
#include "PLKeyEncoding.h"
#include "PLQDraw.h"
#include "PLScrollBarWidget.h"
#include "PLSysCalls.h"
#include "PLTimeTaggedVOSEvent.h"
#include <algorithm>
static const int kOkayButton = 1;
static const int kCancelButton = 2;
static const int kFileList = 3;
static const int kFileListScrollBar = 4;
static const int kFileNameEditBox = 5;
static const int kFileBrowserUIOpenDialogTemplateID = 2001;
static const int kFileBrowserUISaveDialogTemplateID = 2002;
static const int kFileBrowserUIOverwriteDialogTemplateID = 2003;
static const int kFileBrowserUIBadNameDialogTemplateID = 2004;
static const int kOverwriteNoButton = 1;
static const int kOverwriteYesButton = 2;
namespace PortabilityLayer
{
class FileBrowserUIImpl
{
public:
FileBrowserUIImpl();
~FileBrowserUIImpl();
static void PubScrollBarCallback(void *captureContext, Widget *control, int part);
static bool PubEditBoxCharFilter(void *context, uint8_t ch);
static int16_t PubFileBrowserUIFilter(void *context, Dialog *dialog, const TimeTaggedVOSEvent *evt);
static int16_t PubPopUpAlertUIFilter(void *context, Dialog *dialog, const TimeTaggedVOSEvent *evt);
bool AppendName(const char *name, size_t nameLength);
void SortNames();
void DrawFileList();
void CaptureFileListDrag();
void SetScrollOffset(int32_t offset);
uint16_t GetScrollCapacity() const;
void SetUIComponents(Window *window, DrawSurface *surface, const Rect &fileListRect, EditboxWidget *editBox);
PLPasStr GetSelectedFileName() const;
static int16_t PopUpAlert(const Rect &rect, int dialogResID, const DialogTextSubstitutions *substitutions);
private:
typedef PascalStr<255> NameStr_t;
void ScrollBarCallback(Widget *control, int part);
int16_t FileBrowserUIFilter(Dialog *dialog, const TimeTaggedVOSEvent *evt);
int16_t PopUpAlertUIFilter(Dialog *dialog, const TimeTaggedVOSEvent *evt);
static bool NameSortPred(const NameStr_t &a, const NameStr_t &b);
int m_offset;
int m_selectedIndex;
int32_t m_scrollOffset;
int32_t m_fontSpacing;
THandle<NameStr_t> m_names;
size_t m_numNames;
DrawSurface *m_surface;
Window *m_window;
EditboxWidget *m_editBox;
Rect m_rect;
Point m_doubleClickPos;
uint32_t m_doubleClickTime;
bool m_haveFirstClick;
};
FileBrowserUIImpl::FileBrowserUIImpl()
: m_offset(0)
, m_surface(nullptr)
, m_window(nullptr)
, m_editBox(nullptr)
, m_rect(Rect::Create(0, 0, 0, 0))
, m_selectedIndex(-1)
, m_scrollOffset(0)
, m_fontSpacing(1)
, m_numNames(0)
, m_doubleClickPos(Point::Create(0, 0))
, m_doubleClickTime(0)
, m_haveFirstClick(false)
{
}
FileBrowserUIImpl::~FileBrowserUIImpl()
{
m_names.Dispose();
}
void FileBrowserUIImpl::PubScrollBarCallback(void *captureContext, Widget *control, int part)
{
static_cast<FileBrowserUIImpl*>(captureContext)->ScrollBarCallback(control, part);
}
int16_t FileBrowserUIImpl::PubFileBrowserUIFilter(void *context, Dialog *dialog, const TimeTaggedVOSEvent *evt)
{
return static_cast<FileBrowserUIImpl*>(context)->FileBrowserUIFilter(dialog, evt);
}
int16_t FileBrowserUIImpl::PubPopUpAlertUIFilter(void *context, Dialog *dialog, const TimeTaggedVOSEvent *evt)
{
return static_cast<FileBrowserUIImpl*>(context)->PopUpAlertUIFilter(dialog, evt);
}
bool FileBrowserUIImpl::PubEditBoxCharFilter(void *context, uint8_t ch)
{
uint16_t unicodeChar = MacRoman::ToUnicode(ch);
return HostFileSystem::GetInstance()->ValidateFilePathUnicodeChar(unicodeChar);
}
bool FileBrowserUIImpl::AppendName(const char *name, size_t nameLen)
{
MemoryManager *mm = MemoryManager::GetInstance();
if (!m_names)
{
m_names = THandle<NameStr_t>(mm->AllocHandle(0));
if (!m_names)
return false;
}
size_t oldSize = m_names.MMBlock()->m_size;
if (!mm->ResizeHandle(m_names.MMBlock(), oldSize + sizeof(NameStr_t)))
return false;
(*m_names)[m_numNames++] = NameStr_t(nameLen, name);
return true;
}
void FileBrowserUIImpl::SortNames()
{
if (!m_names)
return;
NameStr_t *names = *m_names;
std::sort(names, names + m_numNames, NameSortPred);
}
void FileBrowserUIImpl::DrawFileList()
{
if (!m_names.MMBlock())
return;
PortabilityLayer::RenderedFont *font = GetApplicationFont(12, PortabilityLayer::FontFamilyFlags::FontFamilyFlag_Bold, true);
GpRenderedFontMetrics metrics = font->GetMetrics();
int32_t spacing = metrics.m_linegap;
int32_t glyphOffset = (metrics.m_linegap + metrics.m_ascent) / 2;
Rect itemRect = Rect::Create(m_rect.top, m_rect.left, m_rect.top + spacing, m_rect.right);
itemRect.top -= m_scrollOffset;
itemRect.bottom -= m_scrollOffset;
ResolveCachingColor blackColor = StdColors::Black();
ResolveCachingColor whiteColor = StdColors::White();
ResolveCachingColor focusColor = RGBAColor::Create(153, 153, 255, 255);
m_surface->FillRect(m_rect, whiteColor);
for (size_t i = 0; i < m_numNames; i++)
{
if (m_selectedIndex >= 0 && static_cast<size_t>(m_selectedIndex) == i)
{
Rect focusRect = itemRect.Intersect(m_rect);
if (focusRect.IsValid())
m_surface->FillRect(focusRect, focusColor);
}
Point itemStringPoint = Point::Create(itemRect.left + 2, itemRect.top + glyphOffset);
m_surface->DrawStringConstrained(itemStringPoint, (*m_names)[i].ToShortStr(), m_rect, blackColor, font);
itemRect.top += spacing;
itemRect.bottom += spacing;
}
m_fontSpacing = spacing;
}
void FileBrowserUIImpl::CaptureFileListDrag()
{
}
void FileBrowserUIImpl::SetScrollOffset(int32_t offset)
{
m_scrollOffset = offset;
DrawFileList();
}
uint16_t FileBrowserUIImpl::GetScrollCapacity() const
{
int32_t boxHeight = m_rect.Height();
int32_t overCapacity = (static_cast<int32_t>(m_numNames) * m_fontSpacing - boxHeight);
if (overCapacity < 0)
return 0;
else
return static_cast<uint16_t>(overCapacity);
}
void FileBrowserUIImpl::SetUIComponents(Window *window, DrawSurface *surface, const Rect &rect, EditboxWidget *editbox)
{
m_surface = surface;
m_rect = rect;
m_window = window;
m_editBox = editbox;
}
PLPasStr FileBrowserUIImpl::GetSelectedFileName() const
{
if (m_selectedIndex < 0)
return PSTR("");
else
return (*m_names)[m_selectedIndex].ToShortStr();
}
void FileBrowserUIImpl::ScrollBarCallback(Widget *control, int part)
{
const int pageStepping = 5;
switch (part)
{
case kControlUpButtonPart:
control->SetState(control->GetState() - m_fontSpacing);
break;
case kControlDownButtonPart:
control->SetState(control->GetState() + m_fontSpacing);
break;
case kControlPageUpPart:
control->SetState(control->GetState() - pageStepping * m_fontSpacing);
break;
case kControlPageDownPart:
control->SetState(control->GetState() + pageStepping * m_fontSpacing);
break;
default:
break;
};
SetScrollOffset(control->GetState());
}
int16_t FileBrowserUIImpl::FileBrowserUIFilter(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):
{
Widget *okayButton = dialog->GetItems()[kOkayButton - 1].GetWidget();
if (okayButton->IsEnabled())
{
okayButton->SetHighlightStyle(kControlButtonPart, true);
PLSysCalls::Sleep(8);
okayButton->SetHighlightStyle(kControlButtonPart, false);
hit = kOkayButton;
handledIt = true;
}
}
break;
case PL_KEY_SPECIAL(kEscape):
{
Widget *cancelButton = dialog->GetItems()[kCancelButton - 1].GetWidget();
cancelButton->SetHighlightStyle(kControlButtonPart, true);
PLSysCalls::Sleep(8);
cancelButton->SetHighlightStyle(kControlButtonPart, false);
hit = kCancelButton;
handledIt = true;
}
break;
default:
handledIt = false;
break;
}
}
if (evt->IsLMouseDownEvent())
{
Point mousePt = m_window->MouseToLocal(evt->m_vosEvent.m_event.m_mouseInputEvent);
bool haveDoubleClick = false;
if (m_rect.Contains(mousePt))
{
if (m_haveFirstClick)
{
const uint32_t doubleTime = 30; // PL_NotYetImplemented_TODO: Get this from the system settings
if (mousePt == m_doubleClickPos && evt->m_timestamp - m_doubleClickTime < doubleTime)
haveDoubleClick = true;
}
if (!haveDoubleClick)
{
m_haveFirstClick = true;
m_doubleClickPos = mousePt;
m_doubleClickTime = evt->m_timestamp;
const TimeTaggedVOSEvent *rcvEvt = evt;
TimeTaggedVOSEvent evtHolder;
for (;;)
{
if (rcvEvt)
{
if (rcvEvt->m_vosEvent.m_eventType == GpVOSEventTypes::kMouseInput)
{
mousePt = m_window->MouseToLocal(rcvEvt->m_vosEvent.m_event.m_mouseInputEvent);
if (mousePt != m_doubleClickPos)
m_haveFirstClick = false;
if (m_rect.Contains(mousePt))
{
int32_t selection = (mousePt.v - m_rect.top + m_scrollOffset) / m_fontSpacing;
if (selection < 0 || static_cast<size_t>(selection) >= m_numNames)
selection = -1;
if (selection >= 0)
{
if (selection != m_selectedIndex)
{
m_selectedIndex = selection;
dialog->GetItems()[kOkayButton - 1].GetWidget()->SetEnabled(selection >= 0);
DrawFileList();
}
if (m_editBox)
{
PLPasStr nameStr = (*m_names)[m_selectedIndex].ToShortStr();
m_editBox->SetString(nameStr);
m_editBox->SetSelection(0, nameStr.Length());
}
}
}
}
if (rcvEvt->IsLMouseUpEvent())
break;
}
if (WaitForEvent(&evtHolder, 1))
rcvEvt = &evtHolder;
else
rcvEvt = nullptr;
}
}
}
if (haveDoubleClick && m_selectedIndex >= 0)
{
handledIt = true;
hit = kOkayButton;
}
}
if (!handledIt)
return -1;
return hit;
}
int16_t FileBrowserUIImpl::PopUpAlertUIFilter(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):
{
Widget *okayButton = dialog->GetItems()[kOkayButton - 1].GetWidget();
if (okayButton->IsEnabled())
{
okayButton->SetHighlightStyle(kControlButtonPart, true);
PLSysCalls::Sleep(8);
okayButton->SetHighlightStyle(kControlButtonPart, false);
hit = kOkayButton;
handledIt = true;
}
}
break;
default:
handledIt = false;
break;
}
}
if (!handledIt)
return -1;
return hit;
}
bool FileBrowserUIImpl::NameSortPred(const NameStr_t &a, const NameStr_t &b)
{
const size_t lenA = a.Length();
const size_t lenB = b.Length();
const size_t shorterLength = std::min(lenA, lenB);
int comparison = memcmp(a.UnsafeCharPtr(), b.UnsafeCharPtr(), shorterLength);
if (comparison > 0)
return false;
if (comparison < 0)
return true;
return lenA < lenB;
}
int16_t FileBrowserUIImpl::PopUpAlert(const Rect &rect, int dialogResID, const DialogTextSubstitutions *substitutions)
{
PortabilityLayer::DialogManager *dialogManager = PortabilityLayer::DialogManager::GetInstance();
Dialog *dialog = dialogManager->LoadDialogFromTemplate(dialogResID, rect, true, false, 0, 0, PL_GetPutInFrontWindowPtr(), PSTR(""), substitutions);
const PortabilityLayer::DialogItem &firstItem = *dialog->GetItems().begin();
Rect itemRect = firstItem.GetWidget()->GetRect();
PortabilityLayer::ButtonWidget::DrawDefaultButtonChrome(itemRect, dialog->GetWindow()->GetDrawSurface());
int16_t hit = 0;
do
{
hit = dialog->ExecuteModal(nullptr, PubPopUpAlertUIFilter);
} while (hit != kOkayButton && hit != kCancelButton);
dialog->Destroy();
return hit;
}
bool FileBrowserUI::Prompt(Mode mode, VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText)
{
int dialogID = 0;
if (mode == Mode_Open)
dialogID = kFileBrowserUIOpenDialogTemplateID;
else if (mode == Mode_Save)
dialogID = kFileBrowserUISaveDialogTemplateID;
else
{
assert(false);
return false;
}
FileBrowserUIImpl uiImpl;
// Enumerate files
PortabilityLayer::HostFileSystem *fs = PortabilityLayer::HostFileSystem::GetInstance();
PortabilityLayer::HostDirectoryCursor *dirCursor = fs->ScanDirectory(dirID);
if (!dirCursor)
return false;
const char *fileName;
while (dirCursor->GetNext(fileName))
{
size_t nameLength = strlen(fileName);
if (nameLength < 4)
continue;
const char *nameExt = fileName + (nameLength - 4);
if (!memcmp(nameExt, ".gpf", 4))
{
if (!uiImpl.AppendName(fileName, nameLength - 4))
{
dirCursor->Destroy();
return false;
}
}
}
uiImpl.SortNames();
dirCursor->Destroy();
const int scrollBarWidth = 16;
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();
DialogTextSubstitutions substitutions(promptText);
Dialog *dialog = dialogManager->LoadDialogFromTemplate(dialogID, windowRect, true, false, 0, 0, PL_GetPutInFrontWindowPtr(), PSTR(""), &substitutions);
Window *window = dialog->GetWindow();
DrawSurface *surface = window->GetDrawSurface();
const PortabilityLayer::DialogItem &firstItem = *dialog->GetItems().begin();
Rect itemRect = firstItem.GetWidget()->GetRect();
PortabilityLayer::ButtonWidget::DrawDefaultButtonChrome(itemRect, surface);
// Get item rects
const Rect fileListRect = dialog->GetItems()[kFileList - 1].GetWidget()->GetRect();
const Rect scrollBarRect = dialog->GetItems()[kFileListScrollBar - 1].GetWidget()->GetRect();
EditboxWidget *editbox = nullptr;
if (mode == Mode_Save)
{
editbox = static_cast<EditboxWidget*>(dialog->GetItems()[kFileNameEditBox - 1].GetWidget());
editbox->SetCharacterFilter(&uiImpl, FileBrowserUIImpl::PubEditBoxCharFilter);
editbox->SetCapacity(31);
editbox->SetString(initialFileName);
dialog->GetWindow()->FocusWidget(editbox);
}
// Draw file list frame
surface->FrameRect(fileListRect.Inset(-1, -1), blackColor);
// Draw initial stuff
uiImpl.SetUIComponents(dialog->GetWindow(), surface, fileListRect, editbox);
uiImpl.DrawFileList();
PortabilityLayer::ScrollBarWidget *scrollBar = nullptr;
{
PortabilityLayer::WidgetBasicState state;
state.m_rect = scrollBarRect;
state.m_refConstant = 0;
state.m_window = nullptr;
state.m_max = uiImpl.GetScrollCapacity();
state.m_state = 0;
state.m_defaultCallback = FileBrowserUIImpl::PubScrollBarCallback;
scrollBar = PortabilityLayer::ScrollBarWidget::Create(state, nullptr);
}
dialog->ReplaceWidget(kFileListScrollBar - 1, scrollBar);
window->DrawControls();
int16_t hit = 0;
Window *exclWindow = dialog->GetWindow();
WindowManager::GetInstance()->SwapExclusiveWindow(exclWindow);
do
{
hit = dialog->ExecuteModal(&uiImpl, FileBrowserUIImpl::PubFileBrowserUIFilter);
if (hit == kFileListScrollBar)
uiImpl.SetScrollOffset(scrollBar->GetState());
if (hit == kOkayButton && mode == Mode_Save)
{
HostFileSystem *fs = HostFileSystem::GetInstance();
EditboxWidget *editBox = static_cast<EditboxWidget*>(dialog->GetItems()[kFileNameEditBox - 1].GetWidget());
PLPasStr nameStr = editBox->GetString();
if (nameStr.Length() == 0 || !fs->ValidateFilePath(nameStr.Chars(), nameStr.Length()))
{
PortabilityLayer::HostSystemServices::GetInstance()->Beep();
FileBrowserUIImpl::PopUpAlert(Rect::Create(0, 0, 135, 327), kFileBrowserUIBadNameDialogTemplateID, nullptr);
hit = -1;
}
else if (PortabilityLayer::FileManager::GetInstance()->FileExists(dirID, nameStr))
{
DialogTextSubstitutions substitutions(nameStr);
PortabilityLayer::HostSystemServices::GetInstance()->Beep();
int16_t subHit = FileBrowserUIImpl::PopUpAlert(Rect::Create(0, 0, 135, 327), kFileBrowserUIOverwriteDialogTemplateID, &substitutions);
if (subHit == kOverwriteNoButton)
hit = -1;
}
}
} while (hit != kOkayButton && hit != kCancelButton);
WindowManager::GetInstance()->SwapExclusiveWindow(exclWindow);
bool confirmed = false;
PLPasStr uiFileName;
if (hit == kOkayButton)
{
if (mode == Mode_Open)
{
uiFileName = uiImpl.GetSelectedFileName();
confirmed = true;
}
else if (mode == Mode_Save)
{
uiFileName = editbox->GetString();
confirmed = true;
}
}
if (confirmed)
{
if (uiFileName.Length() > pathCapacity)
confirmed = false;
}
if (confirmed)
{
memcpy(path, uiFileName.Chars(), uiFileName.Length());
outPathLength = uiFileName.Length();
}
dialog->Destroy();
return confirmed;
}
}

View File

@@ -0,0 +1,20 @@
#pragma once
#include "VirtualDirectory.h"
class PLPasStr;
namespace PortabilityLayer
{
class FileBrowserUI
{
public:
enum Mode
{
Mode_Save,
Mode_Open,
};
static bool Prompt(Mode mode, VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText);
};
}

View File

@@ -1,4 +1,6 @@
#include "FileManager.h"
#include "FileBrowserUI.h"
#include "HostFileSystem.h"
#include "HostMemoryBuffer.h"
#include "MemReaderStream.h"
@@ -33,8 +35,8 @@ namespace PortabilityLayer
PLError_t RawOpenFileData(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t creationDisposition, GpIOStream *&outStream) override;
PLError_t RawOpenFileResources(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t creationDisposition, GpIOStream *&outStream) override;
bool PromptSaveFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName) override;
bool PromptOpenFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity) override;
bool PromptSaveFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText) override;
bool PromptOpenFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText) override;
static FileManagerImpl *GetInstance();
@@ -174,18 +176,18 @@ namespace PortabilityLayer
return RawOpenFileFork(dirID, filename, ".gpa", permission, ignoreMeta, createDisposition, outStream);
}
bool FileManagerImpl::PromptSaveFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName)
bool FileManagerImpl::PromptSaveFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText)
{
ExtendedFileName_t extFN;
if (!ConstructFilename(extFN, initialFileName, ""))
return false;
return PortabilityLayer::HostFileSystem::GetInstance()->PromptSaveFile(dirID, path, outPathLength, pathCapacity, extFN);
return FileBrowserUI::Prompt(FileBrowserUI::Mode_Save, dirID, path, outPathLength, pathCapacity, initialFileName, promptText);
}
bool FileManagerImpl::PromptOpenFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity)
bool FileManagerImpl::PromptOpenFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText)
{
return PLSysCalls::PromptOpenFile(dirID, path, outPathLength, pathCapacity);
return FileBrowserUI::Prompt(FileBrowserUI::Mode_Open, dirID, path, outPathLength, pathCapacity, PSTR(""), promptText);
}
FileManagerImpl *FileManagerImpl::GetInstance()

View File

@@ -35,8 +35,8 @@ namespace PortabilityLayer
virtual PLError_t RawOpenFileData(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t createDisposition, GpIOStream *&outStream) = 0;
virtual PLError_t RawOpenFileResources(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t createDisposition, GpIOStream *&outStream) = 0;
virtual bool PromptSaveFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName) = 0;
virtual bool PromptOpenFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity) = 0;
virtual bool PromptSaveFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText) = 0;
virtual bool PromptOpenFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText) = 0;
static FileManager *GetInstance();
};

View File

@@ -20,9 +20,8 @@ namespace PortabilityLayer
virtual bool DeleteFile(VirtualDirectory_t virtualDirectory, const char *path, bool &existed) = 0;
virtual HostDirectoryCursor *ScanDirectory(VirtualDirectory_t virtualDirectory) = 0;
virtual bool PromptSaveFile(VirtualDirectory_t virtualDirectory, char *path, size_t &outPathLength, size_t pathCapacity, const char *initialFileName) = 0;
virtual bool PromptOpenFile(VirtualDirectory_t virtualDirectory, char *path, size_t &outPathLength, size_t pathCapacity) = 0;
virtual bool ValidateFilePath(const char *path, size_t pathLen) const = 0;
virtual bool ValidateFilePathUnicodeChar(uint32_t ch) const = 0;
static HostFileSystem *GetInstance();
static void SetInstance(HostFileSystem *instance);

View File

@@ -229,7 +229,7 @@ namespace PortabilityLayer
{
}
WidgetHandleState_t ButtonWidget::ProcessEvent(const TimeTaggedVOSEvent &evt)
WidgetHandleState_t ButtonWidget::ProcessEvent(void *captureContext, const TimeTaggedVOSEvent &evt)
{
if (!m_visible || !m_enabled)
return WidgetHandleStates::kIgnored;
@@ -240,7 +240,7 @@ namespace PortabilityLayer
if (m_rect.Contains(pt))
{
if (Capture(pt, nullptr) == RegionIDs::kNone)
if (Capture(captureContext, pt, nullptr) == RegionIDs::kNone)
return WidgetHandleStates::kDigested;
else
return WidgetHandleStates::kActivated;
@@ -264,7 +264,7 @@ namespace PortabilityLayer
DrawControl(m_window->GetDrawSurface());
}
int16_t ButtonWidget::Capture(const Point &pos, WidgetUpdateCallback_t callback)
int16_t ButtonWidget::Capture(void *captureContext, const Point &pos, WidgetUpdateCallback_t callback)
{
if (!m_enabled || !m_visible)
return 0;

View File

@@ -30,10 +30,10 @@ namespace PortabilityLayer
void SetString(const PLPasStr &str) override;
PLPasStr GetString() const override;
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt) override;
WidgetHandleState_t ProcessEvent(void *captureContext, const TimeTaggedVOSEvent &evt) override;
void OnEnabledChanged() override;
void OnStateChanged() override;
int16_t Capture(const Point &pos, WidgetUpdateCallback_t callback) override;
int16_t Capture(void *captureContext, const Point &pos, WidgetUpdateCallback_t callback) override;
void SetHighlightStyle(int16_t style, bool enabled) override;
static void DrawDefaultButtonChrome(const Rect &rect, DrawSurface *surface);

View File

@@ -14,7 +14,7 @@ class PLPasStr;
struct Control;
struct Dialog;
typedef int16_t(*DialogFilterFunc_t)(Dialog *dialog, const TimeTaggedVOSEvent *evt);
typedef int16_t(*DialogFilterFunc_t)(void *context, Dialog *dialog, const TimeTaggedVOSEvent *evt);
struct DialogTextSubstitutions
{
@@ -39,7 +39,7 @@ struct Dialog
virtual void SetItemVisibility(unsigned int itemIndex, bool isVisible) = 0;
virtual int16_t ExecuteModal(DialogFilterFunc_t filterFunc) = 0;
virtual int16_t ExecuteModal(void *captureContext, DialogFilterFunc_t filterFunc) = 0;
virtual bool ReplaceWidget(unsigned int itemIndex, PortabilityLayer::Widget *widget) = 0;
};

View File

@@ -35,6 +35,8 @@ namespace PortabilityLayer
, m_isDraggingSelection(false)
, m_dragSelectionStartChar(false)
, m_scrollOffset(0, 0)
, m_characterFilter(nullptr)
, m_characterFilterContext(nullptr)
{
}
@@ -121,17 +123,17 @@ namespace PortabilityLayer
m_length = len;
memcpy(m_chars, str.UChars(), len);
if (m_selStartChar > len)
m_selStartChar = len;
if (m_selEndChar > len)
m_selEndChar = len;
if (m_window)
{
DrawSurface *surface = m_window->GetDrawSurface();
DrawControl(surface);
}
if (m_selStartChar > len)
m_selStartChar = len;
if (m_selEndChar > len)
m_selEndChar = len;
}
PLPasStr EditboxWidget::GetString() const
@@ -166,7 +168,7 @@ namespace PortabilityLayer
Redraw();
}
WidgetHandleState_t EditboxWidget::ProcessEvent(const TimeTaggedVOSEvent &evt)
WidgetHandleState_t EditboxWidget::ProcessEvent(void *captureContext, const TimeTaggedVOSEvent &evt)
{
if (m_isDraggingSelection)
return HandleDragSelection(evt);
@@ -200,6 +202,12 @@ namespace PortabilityLayer
resolvedChar = MacRoman::FromUnicode(ch, keyEvent.m_key.m_unicodeChar);
}
if (resolvedChar)
{
if (m_characterFilter)
resolvedChar = m_characterFilter(m_characterFilterContext, ch);
}
if (resolvedChar)
{
if (ch >= 0x20 && ch <= 0x7e)
@@ -979,4 +987,15 @@ namespace PortabilityLayer
Redraw();
}
}
void EditboxWidget::SetCharacterFilter(void *context, CharacterFilterCallback_t callback)
{
m_characterFilterContext = context;
m_characterFilter = callback;
}
void EditboxWidget::SetCapacity(size_t capacity)
{
m_capacity = std::min<size_t>(255, capacity);
}
}

View File

@@ -11,6 +11,8 @@ namespace PortabilityLayer
class EditboxWidget final : public WidgetSpec<EditboxWidget>
{
public:
typedef bool (*CharacterFilterCallback_t)(void *context, uint8_t character);
EditboxWidget(const WidgetBasicState &state);
~EditboxWidget();
@@ -23,7 +25,7 @@ namespace PortabilityLayer
void GainFocus() override;
void LoseFocus() override;
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt) override;
WidgetHandleState_t ProcessEvent(void *captureContext, const TimeTaggedVOSEvent &evt) override;
Rect GetExpandedRect() const override;
@@ -33,6 +35,9 @@ namespace PortabilityLayer
void SetMultiLine(bool isMultiLine);
void SetCharacterFilter(void *context, CharacterFilterCallback_t callback);
void SetCapacity(size_t capacity);
private:
static const unsigned int kCaratBlinkRate = 20;
static const unsigned int kMouseScrollRate = 20;
@@ -92,5 +97,8 @@ namespace PortabilityLayer
size_t m_dragSelectionStartChar;
uint16_t m_caratTimer;
CharacterFilterCallback_t m_characterFilter;
void *m_characterFilterContext;
};
}

View File

@@ -48,7 +48,7 @@ namespace PortabilityLayer
surface->m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
}
WidgetHandleState_t IconWidget::ProcessEvent(const TimeTaggedVOSEvent &evt)
WidgetHandleState_t IconWidget::ProcessEvent(void *captureContext, const TimeTaggedVOSEvent &evt)
{
if (!m_visible || !m_enabled)
return WidgetHandleStates::kIgnored;

View File

@@ -17,7 +17,7 @@ namespace PortabilityLayer
void DrawControl(DrawSurface *surface) override;
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt) override;
WidgetHandleState_t ProcessEvent(void *captureContext, const TimeTaggedVOSEvent &evt) override;
private:
THandle<PixMapImpl> m_iconImage;

View File

@@ -21,7 +21,7 @@ namespace PortabilityLayer
return true;
}
WidgetHandleState_t InvisibleWidget::ProcessEvent(const TimeTaggedVOSEvent &evt)
WidgetHandleState_t InvisibleWidget::ProcessEvent(void *captureContext, const TimeTaggedVOSEvent &evt)
{
if (!m_visible || !m_enabled)
return WidgetHandleStates::kIgnored;

View File

@@ -12,7 +12,7 @@ namespace PortabilityLayer
bool Init(const WidgetBasicState &state, const void *additionalData) override;
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt) override;
WidgetHandleState_t ProcessEvent(void *captureContext, const TimeTaggedVOSEvent &evt) override;
private:
bool m_clickable;

View File

@@ -39,7 +39,7 @@ namespace PortabilityLayer
return true;
}
WidgetHandleState_t PopupMenuWidget::ProcessEvent(const TimeTaggedVOSEvent &evt)
WidgetHandleState_t PopupMenuWidget::ProcessEvent(void *captureContext, const TimeTaggedVOSEvent &evt)
{
if (evt.IsLMouseDownEvent())
{
@@ -49,7 +49,7 @@ namespace PortabilityLayer
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);
int16_t part = Capture(captureContext, Point::Create(localPoint.m_x, localPoint.m_y), nullptr);
if (part >= 1)
return WidgetHandleStates::kActivated;
else
@@ -60,7 +60,7 @@ namespace PortabilityLayer
return WidgetHandleStates::kIgnored;
}
int16_t PopupMenuWidget::Capture(const Point &pos, WidgetUpdateCallback_t callback)
int16_t PopupMenuWidget::Capture(void *captureContext, const Point &pos, WidgetUpdateCallback_t callback)
{
MenuManager *mm = PortabilityLayer::MenuManager::GetInstance();

View File

@@ -14,8 +14,8 @@ namespace PortabilityLayer
bool Init(const WidgetBasicState &state, const void *additionalData) override;
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt);
int16_t Capture(const Point &pos, WidgetUpdateCallback_t callback);
WidgetHandleState_t ProcessEvent(void *captureContext, const TimeTaggedVOSEvent &evt);
int16_t Capture(void *captureContext, const Point &pos, WidgetUpdateCallback_t callback);
void DrawControl(DrawSurface *surface) override;
void OnStateChanged() override;

View File

@@ -4,6 +4,8 @@
#include "PLTimeTaggedVOSEvent.h"
#include "ResolveCachingColor.h"
#include "PLRegions.h"
namespace PortabilityLayer
{
ScrollBarWidget::ScrollBarWidget(const WidgetBasicState &state)
@@ -15,14 +17,30 @@ namespace PortabilityLayer
, m_laneCapacity(0)
, m_isActive(false)
, m_activePart(0)
, m_callback(state.m_defaultCallback)
{
}
WidgetHandleState_t ScrollBarWidget::ProcessEvent(const TimeTaggedVOSEvent &evt)
WidgetHandleState_t ScrollBarWidget::ProcessEvent(void *captureContext, const TimeTaggedVOSEvent &evt)
{
if (!m_visible || !m_enabled)
return WidgetHandleStates::kIgnored;
if (evt.IsLMouseDownEvent())
{
const Point pt = m_window->MouseToLocal(evt.m_vosEvent.m_event.m_mouseInputEvent);
if (m_rect.Contains(pt))
{
if (Capture(captureContext, pt, m_callback) == RegionIDs::kNone)
return WidgetHandleStates::kDigested;
else
return WidgetHandleStates::kActivated;
}
else
return WidgetHandleStates::kIgnored;
}
return WidgetHandleStates::kIgnored;
}
@@ -279,19 +297,19 @@ namespace PortabilityLayer
}
}
int16_t ScrollBarWidget::Capture(const Point &pos, WidgetUpdateCallback_t callback)
int16_t ScrollBarWidget::Capture(void *captureContext, const Point &pos, WidgetUpdateCallback_t callback)
{
int part = ResolvePart(pos);
if (!part)
return 0;
if (part == kControlIndicatorPart)
return CaptureIndicator(pos, callback);
return CaptureIndicator(captureContext, pos, callback);
else
return CaptureScrollSegment(pos, part, callback);
return CaptureScrollSegment(captureContext, pos, part, callback);
}
int16_t ScrollBarWidget::CaptureScrollSegment(const Point &pos, int part, WidgetUpdateCallback_t callback)
int16_t ScrollBarWidget::CaptureScrollSegment(void *captureContext, const Point &pos, int part, WidgetUpdateCallback_t callback)
{
int tickDelay = 15;
@@ -308,7 +326,7 @@ namespace PortabilityLayer
if (ticksUntilIterate == 0)
{
if (m_isActive)
IterateScrollSegment(part, callback);
IterateScrollSegment(captureContext, part, callback);
ticksUntilIterate = tickDelay;
}
@@ -349,7 +367,7 @@ namespace PortabilityLayer
}
}
int16_t ScrollBarWidget::CaptureIndicator(const Point &pos, WidgetUpdateCallback_t callback)
int16_t ScrollBarWidget::CaptureIndicator(void *captureContext, const Point &pos, WidgetUpdateCallback_t callback)
{
const bool isHorizontal = IsHorizontal();
@@ -428,10 +446,10 @@ namespace PortabilityLayer
}
}
void ScrollBarWidget::IterateScrollSegment(int part, WidgetUpdateCallback_t callback)
void ScrollBarWidget::IterateScrollSegment(void *captureContext, int part, WidgetUpdateCallback_t callback)
{
if (callback != nullptr)
callback(this, part);
callback(captureContext, this, part);
}
int ScrollBarWidget::ResolvePart(const Point &point) const

View File

@@ -15,7 +15,7 @@ namespace PortabilityLayer
bool Init(const WidgetBasicState &state, const void *additionalData) override;
void OnEnabledChanged() override;
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt) override;
WidgetHandleState_t ProcessEvent(void *captureContext, const TimeTaggedVOSEvent &evt) override;
void DrawControl(DrawSurface *surface) override;
void SetState(int16_t state) override;
@@ -24,7 +24,7 @@ namespace PortabilityLayer
void SetMin(int32_t v) override;
void SetMax(int32_t v) override;
int16_t Capture(const Point &pos, WidgetUpdateCallback_t callback) override;
int16_t Capture(void *captureContext, const Point &pos, WidgetUpdateCallback_t callback) override;
int ResolvePart(const Point &point) const override;
@@ -39,9 +39,9 @@ namespace PortabilityLayer
static void DrawBeveledBox(DrawSurface *surface, const Rect &rect);
int16_t CaptureScrollSegment(const Point &pos, int part, WidgetUpdateCallback_t callback);
int16_t CaptureIndicator(const Point &pos, WidgetUpdateCallback_t callback);
void IterateScrollSegment(int part, WidgetUpdateCallback_t callback);
int16_t CaptureScrollSegment(void *captureContext, const Point &pos, int part, WidgetUpdateCallback_t callback);
int16_t CaptureIndicator(void *captureContext, const Point &pos, WidgetUpdateCallback_t callback);
void IterateScrollSegment(void *captureContext, int part, WidgetUpdateCallback_t callback);
int32_t m_min;
int32_t m_max;
@@ -51,5 +51,7 @@ namespace PortabilityLayer
bool m_isActive;
int m_activePart;
WidgetUpdateCallback_t m_callback;
};
}

View File

@@ -175,63 +175,4 @@ namespace PLSysCalls
AnimationManager::GetInstance()->TickPlayers(ticks);
}
}
static void PromptOpenFileCallback(const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue)
{
bool result = PortabilityLayer::HostFileSystem::GetInstance()->PromptOpenFile(static_cast<PortabilityLayer::VirtualDirectory_t>(args[0].m_int), static_cast<char*>(args[1].m_pointer), *static_cast<size_t*>(args[2].m_pointer), args[3].m_uint);
returnValue->m_uint = (result ? 1 : 0);
}
bool PromptOpenFile(PortabilityLayer::VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity)
{
PortabilityLayer::HostSuspendCallArgument cbArgs[4];
cbArgs[0].m_int = static_cast<int32_t>(dirID);
cbArgs[1].m_pointer = path;
cbArgs[2].m_pointer = &outPathLength;
cbArgs[3].m_size = pathCapacity;
PortabilityLayer::HostSuspendCallArgument cbReturnValue;
PortabilityLayer::HostSuspendCallArgument dispatchArgs[3];
dispatchArgs[0].m_functionPtr = PromptOpenFileCallback;
dispatchArgs[1].m_constPointer = cbArgs;
dispatchArgs[2].m_pointer = &cbReturnValue;
PortabilityLayer::SuspendApplication(PortabilityLayer::HostSuspendCallID_CallOnVOSThread, dispatchArgs, nullptr);
return cbReturnValue.m_uint != 0;
}
static void PromptSaveFileCallback(const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue)
{
bool result = PortabilityLayer::HostFileSystem::GetInstance()->PromptSaveFile(
static_cast<PortabilityLayer::VirtualDirectory_t>(args[0].m_int),
static_cast<char*>(args[1].m_pointer),
*static_cast<size_t*>(args[2].m_pointer),
args[3].m_uint,
static_cast<const char*>(args[4].m_constPointer));
returnValue->m_uint = (result ? 1 : 0);
}
bool PromptSaveFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, char *path, size_t &outPathLength, size_t pathCapacity, const char *initialFileName)
{
PortabilityLayer::HostSuspendCallArgument cbArgs[5];
cbArgs[0].m_int = static_cast<int32_t>(virtualDirectory);
cbArgs[1].m_pointer = path;
cbArgs[2].m_pointer = &outPathLength;
cbArgs[3].m_size = pathCapacity;
cbArgs[3].m_constPointer = initialFileName;
PortabilityLayer::HostSuspendCallArgument cbReturnValue;
PortabilityLayer::HostSuspendCallArgument dispatchArgs[3];
dispatchArgs[0].m_functionPtr = PromptSaveFileCallback;
dispatchArgs[1].m_constPointer = cbArgs;
dispatchArgs[2].m_pointer = &cbReturnValue;
PortabilityLayer::SuspendApplication(PortabilityLayer::HostSuspendCallID_CallOnVOSThread, dispatchArgs, nullptr);
return cbReturnValue.m_uint != 0;
}
}

View File

@@ -7,6 +7,4 @@
namespace PLSysCalls
{
void Sleep(uint32_t ticks);
bool PromptOpenFile(PortabilityLayer::VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity);
bool PromptSaveFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, char *path, size_t &outPathLength, size_t pathCapacity, const char *initialFileName);
}

View File

@@ -13,17 +13,18 @@ namespace PortabilityLayer
, m_max(0)
, m_state(0)
, m_enabled(true)
, m_defaultCallback(nullptr)
{
}
WidgetHandleState_t Widget::ProcessEvent(const TimeTaggedVOSEvent &evt)
WidgetHandleState_t Widget::ProcessEvent(void *captureContext, const TimeTaggedVOSEvent &evt)
{
(void)evt;
return WidgetHandleStates::kIgnored;
}
int16_t Widget::Capture(const Point &pos, WidgetUpdateCallback_t callback)
int16_t Widget::Capture(void *captureContext, const Point &pos, WidgetUpdateCallback_t callback)
{
return 0;
}
@@ -64,6 +65,11 @@ namespace PortabilityLayer
OnEnabledChanged();
}
bool Widget::IsEnabled() const
{
return m_enabled;
}
void Widget::SetState(int16_t state)
{
m_state = state;

View File

@@ -25,7 +25,7 @@ namespace PortabilityLayer
typedef WidgetHandleStates::WidgetHandleState WidgetHandleState_t;
typedef void (*WidgetUpdateCallback_t)(Widget *control, int part);
typedef void (*WidgetUpdateCallback_t)(void *captureContext, Widget *control, int part);
struct WidgetBasicState
{
@@ -40,6 +40,8 @@ namespace PortabilityLayer
int16_t m_state;
int16_t m_resID;
bool m_enabled;
WidgetUpdateCallback_t m_defaultCallback;
};
class Widget
@@ -47,8 +49,8 @@ namespace PortabilityLayer
public:
virtual bool Init(const WidgetBasicState &state, const void *additionalData) = 0;
virtual void Destroy() = 0;
virtual WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt);
virtual int16_t Capture(const Point &pos, WidgetUpdateCallback_t callback);
virtual WidgetHandleState_t ProcessEvent(void *captureContext, const TimeTaggedVOSEvent &evt);
virtual int16_t Capture(void *captureContext, const Point &pos, WidgetUpdateCallback_t callback);
virtual void DrawControl(DrawSurface *surface);
virtual void SetMin(int32_t v);
@@ -58,6 +60,7 @@ namespace PortabilityLayer
void Resize(uint16_t width, uint16_t height);
void SetEnabled(bool enabled);
bool IsEnabled() const;
virtual void SetState(int16_t state);
int16_t GetState() const;

View File

@@ -160,6 +160,7 @@
<ClInclude Include="DialogManager.h" />
<ClInclude Include="DisplayDeviceManager.h" />
<ClInclude Include="EllipsePlotter.h" />
<ClInclude Include="FileBrowserUI.h" />
<ClInclude Include="FileManager.h" />
<ClInclude Include="FilePermission.h" />
<ClInclude Include="FilePos.h" />
@@ -303,6 +304,7 @@
<ClCompile Include="DialogManager.cpp" />
<ClCompile Include="DisplayDeviceManager.cpp" />
<ClCompile Include="EllipsePlotter.cpp" />
<ClCompile Include="FileBrowserUI.cpp" />
<ClCompile Include="FileManager.cpp" />
<ClCompile Include="FontFamily.cpp" />
<ClCompile Include="FontManager.cpp" />

View File

@@ -459,6 +459,9 @@
<ClInclude Include="HostLogDriver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FileBrowserUI.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CFileStream.cpp">
@@ -731,5 +734,8 @@
<ClCompile Include="HostInputDriver.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FileBrowserUI.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>