#pragma once #include "PascalStr.h" #include "PLWidgets.h" #include "Vec2i.h" struct DrawSurface; 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; void GainFocus() override; void LoseFocus() override; WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt) override; Rect GetExpandedRect() const override; bool HandlesTickEvents() const; void SetSelection(size_t startChar, size_t endChar); void SetMultiLine(bool isMultiLine); private: static const unsigned int kCaratBlinkRate = 20; enum CaratSelectionAnchor { CaratSelectionAnchor_Start, CaratSelectionAnchor_End }; void OnTick() override; void Redraw(); void HandleCharacter(uint8_t keyChar, const uint32_t numRepeatsRequested); void HandleBackspace(const uint32_t numRepeatsRequested); void HandleForwardDelete(const uint32_t numRepeatsRequested); void HandleUpArrow(const uint32_t numRepeatsRequested, bool shiftHeld); void HandleDownArrow(const uint32_t numRepeatsRequested, bool shiftHeld); void HandleLeftArrow(const uint32_t numRepeatsRequested, bool shiftHeld); void HandleRightArrow(const uint32_t numRepeatsRequested, bool shiftHeld); size_t FindVerticalMovementCaratPos(const Vec2i &desiredPos, bool &isOutOfRange) const; void HandleKeyMoveCarat(size_t newPos, bool shiftHeld); WidgetHandleState_t HandleDragSelection(const TimeTaggedVOSEvent &evt); void DrawSelection(DrawSurface *surface, const Vec2i &basePoint) const; Vec2i ResolveCaratPos(const Vec2i &basePoint, PortabilityLayer::RenderedFont *rfont) const; Vec2i ResolveBasePoint() const; size_t ResolveCaratChar() const; PortabilityLayer::FontFamily *GetFontFamily() const; PortabilityLayer::RenderedFont *GetRenderedFont() const; uint8_t *m_chars; size_t m_capacity; size_t m_length; size_t m_selStartChar; size_t m_selEndChar; CaratSelectionAnchor m_caratSelectionAnchor; Vec2i m_caratScrollPosition; bool m_caratScrollLocked; bool m_hasFocus; bool m_isMultiLine; bool m_isDraggingSelection; size_t m_dragSelectionStartChar; uint16_t m_caratTimer; }; }