diff --git a/PortabilityLayer/DialogManager.cpp b/PortabilityLayer/DialogManager.cpp index 3afca08..b2e89b8 100644 --- a/PortabilityLayer/DialogManager.cpp +++ b/PortabilityLayer/DialogManager.cpp @@ -8,6 +8,7 @@ #include "PLButtonWidget.h" #include "PLCheckboxWidget.h" #include "PLDialogs.h" +#include "PLEditboxWidget.h" #include "PLIconWidget.h" #include "PLImageWidget.h" #include "PLInvisibleWidget.h" @@ -315,6 +316,8 @@ namespace PortabilityLayer widget = RadioButtonWidget::Create(basicState); break; case SerializedDialogItemTypeCodes::kEditBox: + widget = EditboxWidget::Create(basicState); + break; default: widget = InvisibleWidget::Create(basicState); break; diff --git a/PortabilityLayer/PLEditboxWidget.cpp b/PortabilityLayer/PLEditboxWidget.cpp new file mode 100644 index 0000000..d9f3c88 --- /dev/null +++ b/PortabilityLayer/PLEditboxWidget.cpp @@ -0,0 +1,72 @@ +#include "PLEditboxWidget.h" +#include "PLStandardColors.h" +#include "MemoryManager.h" +#include "FontFamily.h" + +#include + +namespace PortabilityLayer +{ + EditboxWidget::EditboxWidget(const WidgetBasicState &state) + : WidgetSpec(state) + , m_capacity(255) + , m_length(0) + , m_chars(nullptr) + , m_selStartChar(0) + , m_selEndChar(0) + { + } + + EditboxWidget::~EditboxWidget() + { + PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance(); + + if (m_chars) + mm->Release(m_chars); + } + + bool EditboxWidget::Init(const WidgetBasicState &state) + { + PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance(); + m_capacity = 255; + + m_chars = static_cast(mm->Alloc(m_capacity * sizeof(m_chars[0]))); + if (!m_chars) + return false; + + return true; + } + + void EditboxWidget::EditboxWidget::DrawControl(DrawSurface *surface) + { + const Rect textRect = m_rect; + const Rect innerRect = textRect.Inset(-2, -2); + const Rect outerRect = innerRect.Inset(-1, -1); + + surface->SetForeColor(StdColors::Black()); + surface->FillRect(outerRect); + surface->SetForeColor(StdColors::White()); + surface->FillRect(innerRect); + + surface->SetForeColor(StdColors::Black()); + surface->SetSystemFont(12, PortabilityLayer::FontFamilyFlag_None); + int32_t ascender = surface->MeasureFontAscender(); + + Point basePoint = Point::Create(textRect.left, (textRect.top + textRect.bottom + ascender + 1) / 2); + surface->DrawStringConstrained(basePoint, this->GetString(), true, m_rect); + } + + void EditboxWidget::SetString(const PLPasStr &str) + { + const size_t len = std::min(m_capacity, str.Length()); + + m_length = len; + memcpy(m_chars, str.UChars(), len); + } + + PLPasStr EditboxWidget::GetString() const + { + const uint8_t len = static_cast(std::min(255, m_length)); + return PLPasStr(len, reinterpret_cast(m_chars)); + } +} diff --git a/PortabilityLayer/PLEditboxWidget.h b/PortabilityLayer/PLEditboxWidget.h new file mode 100644 index 0000000..8b30cd3 --- /dev/null +++ b/PortabilityLayer/PLEditboxWidget.h @@ -0,0 +1,27 @@ +#pragma once + +#include "PascalStr.h" +#include "PLWidgets.h" + +namespace PortabilityLayer +{ + class EditboxWidget final : public WidgetSpec + { + public: + EditboxWidget(const WidgetBasicState &state); + ~EditboxWidget(); + + bool Init(const WidgetBasicState &state) override; + + void DrawControl(DrawSurface *surface) override; + void SetString(const PLPasStr &str) override; + PLPasStr GetString() const override; + + private: + uint8_t *m_chars; + size_t m_capacity; + size_t m_length; + size_t m_selStartChar; + size_t m_selEndChar; + }; +} diff --git a/PortabilityLayer/PLLabelWidget.cpp b/PortabilityLayer/PLLabelWidget.cpp index d043673..2e6f540 100644 --- a/PortabilityLayer/PLLabelWidget.cpp +++ b/PortabilityLayer/PLLabelWidget.cpp @@ -31,10 +31,6 @@ namespace PortabilityLayer void LabelWidget::DrawControl(DrawSurface *surface) { - // FIXME: This is kind of bad - surface->SetForeColor(StdColors::White()); - surface->FillRect(m_rect); - surface->SetSystemFont(12, PortabilityLayer::FontFamilyFlag_Bold); surface->SetForeColor(StdColors::Black()); diff --git a/PortabilityLayer/PLQDraw.cpp b/PortabilityLayer/PLQDraw.cpp index cd5c07d..9d57c0e 100644 --- a/PortabilityLayer/PLQDraw.cpp +++ b/PortabilityLayer/PLQDraw.cpp @@ -309,8 +309,8 @@ static void DrawGlyph(PortabilityLayer::QDState *qdState, PixMap *pixMap, const if (clampedLeftCoord >= clampedRightCoord || clampedTopCoord >= clampedBottomCoord) return; - const uint32_t firstOutputRow = clampedTopCoord - rect.top; - const uint32_t firstOutputCol = clampedLeftCoord - rect.left; + const uint32_t firstOutputRow = clampedTopCoord; + const uint32_t firstOutputCol = clampedLeftCoord; const uint32_t firstInputRow = clampedTopCoord - topCoord; const uint32_t firstInputCol = clampedLeftCoord - leftCoord; @@ -394,6 +394,11 @@ static void DrawGlyph(PortabilityLayer::QDState *qdState, PixMap *pixMap, const } void DrawSurface::DrawString(const Point &point, const PLPasStr &str, bool aa) +{ + DrawStringConstrained(point, str, aa, Rect::CreateLargest()); +} + +void DrawSurface::DrawStringConstrained(const Point &point, const PLPasStr &str, bool aa, const Rect &constraintRect) { PortabilityLayer::QDPort *port = &m_port; @@ -413,10 +418,10 @@ void DrawSurface::DrawString(const Point &point, const PLPasStr &str, bool aa) PixMap *pixMap = *port->GetPixMap(); - const Rect rect = pixMap->m_rect; + const Rect rect = pixMap->m_rect.Intersect(constraintRect); if (!rect.IsValid()) - return; // ??? + return; Point paraStartPos = penPos; diff --git a/PortabilityLayer/PortabilityLayer.vcxproj b/PortabilityLayer/PortabilityLayer.vcxproj index d74c5ee..3f2da7c 100644 --- a/PortabilityLayer/PortabilityLayer.vcxproj +++ b/PortabilityLayer/PortabilityLayer.vcxproj @@ -206,6 +206,7 @@ + @@ -330,6 +331,7 @@ + diff --git a/PortabilityLayer/PortabilityLayer.vcxproj.filters b/PortabilityLayer/PortabilityLayer.vcxproj.filters index 3e11827..19160cb 100644 --- a/PortabilityLayer/PortabilityLayer.vcxproj.filters +++ b/PortabilityLayer/PortabilityLayer.vcxproj.filters @@ -468,6 +468,9 @@ Header Files + + Header Files + @@ -734,5 +737,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/PortabilityLayer/QDGraf.h b/PortabilityLayer/QDGraf.h index 6057135..e4c74b2 100644 --- a/PortabilityLayer/QDGraf.h +++ b/PortabilityLayer/QDGraf.h @@ -82,6 +82,7 @@ struct DrawSurface final void SetApplicationFont(int size, int variationFlags); void SetSystemFont(int size, int variationFlags); void DrawString(const Point &point, const PLPasStr &str, bool aa); + void DrawStringConstrained(const Point &point, const PLPasStr &str, bool aa, const Rect &constraintRect); void DrawStringWrap(const Point &point, const Rect &constrainRect, const PLPasStr &str, bool aa); size_t MeasureString(const PLPasStr &str); diff --git a/PortabilityLayer/SharedTypes.h b/PortabilityLayer/SharedTypes.h index b2017ef..d88f68d 100644 --- a/PortabilityLayer/SharedTypes.h +++ b/PortabilityLayer/SharedTypes.h @@ -47,6 +47,7 @@ struct Rect static Rect Create(int16_t top, int16_t left, int16_t bottom, int16_t right); static Rect CreateFromPoints(const Point &topLeft, const Point &bottomRight); + static Rect CreateLargest(); }; struct BERect @@ -244,3 +245,8 @@ inline Rect Rect::CreateFromPoints(const Point &topLeft, const Point &bottomRigh { return Rect::Create(topLeft.v, topLeft.h, bottomRight.v, bottomRight.h); } + +inline Rect Rect::CreateLargest() +{ + return Rect::Create(-0x8000, -0x8000, 0x7fff, 0x7fff); +}