PEBL 2.2
Psychology Experiment Building Language - Cross-platform psychological experiment development system
PlatformTextBox Class Reference

Validator platform textbox - no rendering, used only for compilation. More...

#include <PlatformTextBox.h>

Inheritance diagram for PlatformTextBox:
PlatformWidget PTextBox PlatformWidget PTextBox PWidget PWidget PTextObject PWidget PWidget PTextObject PEBLObjectBase PEBLObjectBase PWidget PEBLObjectBase PEBLObjectBase PWidget PEBLObjectBase PEBLObjectBase

Public Member Functions

 PlatformTextBox (std::string text, counted_ptr< PEBLObjectBase > font, int width, int height)
 
 PlatformTextBox (const PlatformTextBox &textbox)
 This copy constructor isn't const because the font is shared.
 
virtual ~PlatformTextBox ()
 Standard Destructor.
 
virtual bool RenderText ()
 
virtual bool SetProperty (std::string, Variant v)
 
virtual Variant GetProperty (std::string name) const
 
virtual void SetFont (counted_ptr< PEBLObjectBase > font)
 
virtual void SetText (std::string text)
 
virtual void SetHeight (int h)
 
virtual void SetWidth (int w)
 
virtual counted_ptr< PEBLObjectBaseGetFont () const
 
virtual bool Draw ()
 This method initiates everything needed to display the main window

 
virtual void HandleKeyPress (int keycode, int modkeys, Uint16 unicode)
 
virtual void HandleTextInput (std::string input)
 
virtual std::string ObjectName () const
 
virtual int FindCursorPosition (long int x, long int y)
 
virtual void SetEditable (bool val)
 
Variant GetLineBreaks ()
 
 PlatformTextBox (const std::string &text, counted_ptr< PEBLObjectBase > font, int width, int height)
 
 PlatformTextBox (PlatformTextBox &textbox)
 
virtual ~PlatformTextBox ()
 
virtual bool Draw ()
 This method initiates everything needed to display the main window

 
virtual std::string ObjectName () const
 
virtual int FindCursorPosition (long int x, long int y)
 
virtual Variant GetLineBreaks ()
 
virtual void SetFont (counted_ptr< PEBLObjectBase > font)
 
virtual bool SetProperty (std::string name, Variant v)
 
virtual ObjectValidationError ValidateProperty (std::string name, Variant v) const
 
virtual ObjectValidationError ValidateProperty (std::string name) const
 
virtual void SetPosition (pInt x, pInt y)
 This sets the widget's position on its parent widget.
 
- Public Member Functions inherited from PlatformWidget
 PlatformWidget ()
 
virtual ~PlatformWidget ()
 
virtual SDL_Texture * GetSDL_Texture ()
 Used to extract an SDL surface from the widget. Used by children drawing themselves on their parent.
 
void SetParent (PlatformWidget *parent)
 
SDL_Surface * GetSurface ()
 
virtual bool SetRenderer (SDL_Renderer *renderer)
 
SDL_Renderer * GetRenderer ()
 
virtual bool AddToParentWidget (PlatformWidget *parent)
 
virtual bool AddSubWidget (PlatformWidget *widget)
 
virtual bool RemoveSubWidget (PlatformWidget *widget)
 
virtual bool RemoveSubWidgets ()
 
virtual bool RotoZoom (double angle, double zoomx, double zoomy, int smooth)
 This uses the SDL_gfx package to 'rotozoom'.
 
bool SetPoint (int x, int y, PColor col)
 
PColor GetPixel (int x, int y)
 
 PlatformWidget ()
 
 PlatformWidget (pInt x, pInt y, pInt width, pInt height, bool visible)
 
virtual ~PlatformWidget ()
 
virtual bool RotoZoom (pDouble angle, pDouble zoomx, pDouble zoomy, pInt smooth)
 
virtual bool SetPoint (pInt x, pInt y, PColor col)
 
virtual PColor GetPixel (pInt x, pInt y)
 
- Public Member Functions inherited from PWidget
 PWidget ()
 
 PWidget (const PWidget &pw)
 
 PWidget (pInt x, pInt y, pInt width, pInt height, bool visible)
 
virtual ~PWidget ()
 
virtual void SetParent (PWidget *widget)
 This unconditionally sets the parent widget.
 
virtual PWidgetGetParent ()
 
virtual bool IsParent (PWidget *parent)
 
virtual void SetZoomX (pDouble x)
 This sets the widget's position on its parent widget.
 
virtual void SetZoomY (pDouble x)
 This sets the widget's position on its parent widget.
 
virtual void SetRotation (pDouble x)
 This sets the widget's position on its parent widget.
 
virtual void SetWidth (pInt w)
 
virtual void SetHeight (pInt h)
 
virtual pInt GetX () const
 
virtual pInt GetY () const
 
virtual pInt GetWidth () const
 
virtual pInt GetHeight () const
 
virtual void SetBackgroundColor (const PColor &color)
 
virtual PColor GetBackgroundColor ()
 
virtual bool AddSubWidget (PWidget *widget)
 
virtual bool RemoveSubWidget (PWidget *widget)
 
virtual bool RemoveLastSubWidget ()
 This is probably pretty useless.
 
virtual void Show ()
 
virtual void Hide ()
 
virtual bool IsVisible () const
 
- Public Member Functions inherited from PEBLObjectBase
 PEBLObjectBase ()
 Standard Constructor.
 
 PEBLObjectBase (ComplexDataType cdt)
 Standard Constructor.
 
 PEBLObjectBase (const PEBLObjectBase &pob)
 
virtual ~PEBLObjectBase ()
 Standard Destructor.
 
virtual bool InitializeProperty (std::string name, Variant v)
 
Variant GetProperty (std::string) const
 
ComplexDataType GetType ()
 
virtual std::ostream & PrintProperties (std::ostream &out)
 
virtual Variant GetPropertyList ()
 
- Public Member Functions inherited from PTextBox
 PTextBox ()
 
 PTextBox (std::string text, int width, int height)
 
 PTextBox (PTextBox &textbox)
 
virtual ~PTextBox ()
 
virtual void InsertText (const std::string character)
 
virtual void DeleteText (int length)
 
virtual bool GetEditable ()
 
virtual void SetCursorPosition (unsigned long int pos)
 
virtual unsigned long int GetCursorPosition ()
 
virtual long unsigned int IncrementCursor ()
 
virtual long unsigned int DecrementCursor ()
 
virtual void SetLineWrap (bool state)
 
virtual void SetJustify (Variant j)
 
virtual bool AtPrintableCharacter (unsigned long int x)
 
- Public Member Functions inherited from PTextObject
 PTextObject ()
 
 PTextObject (const std::string &text)
 
 PTextObject (PTextObject &object)
 
virtual ~PTextObject ()
 
virtual void SetText (const std::string &text)
 
virtual void SetDirection (int i)
 
virtual std::string GetText () const
 
virtual unsigned long int GetNumCharacters ()
 

Protected Member Functions

virtual std::ostream & SendToStream (std::ostream &out) const
 An inheritable printing class used by PEBLObjectBase::operator<<.
 
virtual std::ostream & SendToStream (std::ostream &out) const
 An inheritable printing class used by PEBLObjectBase::operator<<.
 
- Protected Member Functions inherited from PlatformWidget
virtual void PrintSubWidgets (std::ostream &out) const
 
virtual bool LockSurface ()
 This needs to be used on some platforms/video cards.
 
virtual bool UnlockSurface ()
 This needs to be used on some platforms/video cards.
 

Protected Attributes

std::vector< int > mBreaks
 
- Protected Attributes inherited from PlatformWidget
pInt mTextureWidth
 
pInt mTextureHeight
 
bool mNeedsTexture
 
SDL_Texture * mTexture
 
SDL_Surface * mSurface
 
SDL_Renderer * mRenderer
 
- Protected Attributes inherited from PWidget
pInt mX
 
pInt mY
 
pInt mDrawX
 
pInt mDrawY
 
pInt mWidth
 
pInt mHeight
 
pDouble mZoomX
 
pDouble mZoomY
 
pDouble mRotation
 
PColor mBackgroundColor
 The background color of the widget. if alpha = 0, will not be painted.
 
std::list< PWidget * > mSubWidgets
 
bool mIsVisible
 
PWidgetmParent
 
- Protected Attributes inherited from PEBLObjectBase
ComplexDataType mCDT
 
std::map< std::string, VariantmProperties
 
- Protected Attributes inherited from PTextBox
bool mEditable
 
unsigned long int mCursorPos
 
bool mCursorChanged
 
bool mLineWrap
 
Variant mJustify
 
- Protected Attributes inherited from PTextObject
bool mChanged
 
std::string mText
 
int mDirection
 

Detailed Description

Validator platform textbox - no rendering, used only for compilation.

This class defines an SDL-specific text box.

Definition at line 55 of file sdl/PlatformTextBox.h.

Constructor & Destructor Documentation

◆ PlatformTextBox() [1/4]

PlatformTextBox::PlatformTextBox ( std::string  text,
counted_ptr< PEBLObjectBase font,
int  width,
int  height 
)

◆ PlatformTextBox() [2/4]

PlatformTextBox::PlatformTextBox ( const PlatformTextBox textbox)

This copy constructor isn't const because the font is shared.

Definition at line 147 of file sdl/PlatformTextBox.cpp.

147 :
148 PTextObject(text.GetText()), // Must initialize virtual base class directly
150 PTextBox(text.GetText(), (int)(text.GetWidth()), (int)(text.GetHeight()))
151
152
153{
154 mSurface = NULL;
155 mTexture = NULL;
156 mRenderer = NULL;
157 mIsUTF8= utf8::is_valid(mText.begin(),mText.end());
159 mWidth = text.GetWidth();
160 mHeight = text.GetHeight();
163
164 SetFont(text.GetFont());
165 mChanged = true;
166 // Don't call Draw() here - no renderer yet since object hasn't been added to window
167 // Draw() will be called when object is added to window or explicitly drawn
168}
#define NULL
Definition BinReloc.cpp:317
@ CDT_TEXTBOX
Definition PEBLObject.h:57
ComplexDataType mCDT
Definition PEBLObject.h:109
std::string mText
Definition PTextObject.h:70
pInt mWidth
Definition PWidget.h:136
pInt mHeight
Definition PWidget.h:136
virtual void SetFont(counted_ptr< PEBLObjectBase > font)
SDL_Surface * mSurface
SDL_Texture * mTexture
SDL_Renderer * mRenderer

References CDT_TEXTBOX, GetFont(), PWidget::GetHeight(), PWidget::GetWidth(), PEBLObjectBase::mCDT, PTextObject::mChanged, PWidget::mHeight, PlatformWidget::mRenderer, PlatformWidget::mSurface, PTextObject::mText, PlatformWidget::mTexture, PlatformWidget::mTextureHeight, PlatformWidget::mTextureWidth, PWidget::mWidth, NULL, and SetFont().

◆ ~PlatformTextBox() [1/2]

PlatformTextBox::~PlatformTextBox ( )
virtual

Standard Destructor.

Definition at line 172 of file sdl/PlatformTextBox.cpp.

173{
174
175 // PlatformWidget frees mSurface,
176}

◆ PlatformTextBox() [3/4]

PlatformTextBox::PlatformTextBox ( const std::string &  text,
counted_ptr< PEBLObjectBase font,
int  width,
int  height 
)

Definition at line 27 of file validator/PlatformTextBox.cpp.

29 : PTextBox(text, width, height), mFontObject(font) {
30}

◆ PlatformTextBox() [4/4]

PlatformTextBox::PlatformTextBox ( PlatformTextBox textbox)

Definition at line 32 of file validator/PlatformTextBox.cpp.

33 : PTextBox(textbox), mFontObject(textbox.mFontObject) {
34}

◆ ~PlatformTextBox() [2/2]

virtual PlatformTextBox::~PlatformTextBox ( )
virtual

Member Function Documentation

◆ Draw() [1/2]

bool PlatformTextBox::Draw ( )
virtual

This method initiates everything needed to display the main window

Reimplemented from PlatformWidget.

Definition at line 1651 of file sdl/PlatformTextBox.cpp.

1652{
1653 // Check if font properties changed and update widget bgcolor if needed
1654 if(GetPlatformFont()->HasChanged())
1655 {
1656 PWidget::SetBackgroundColor(GetPlatformFont()->GetBackgroundColor());
1657 mChanged = true;
1658 GetPlatformFont()->ClearChanged();
1659 }
1660
1661 // CRITICAL: Always call FindBreaks() when text has changed
1662 // This was in the backup version and is needed for proper rendering
1663 if(mChanged)
1664 {
1665 FindBreaks();
1666 }
1667
1668 if(mChanged)
1669 {
1670 // Check if adaptive mode is enabled
1671 Variant isAdaptiveVar = PEBLObjectBase::GetProperty("ISADAPTIVE");
1672 if (isAdaptiveVar.GetInteger()) {
1673 // Track whether this is the first time we're creating an adaptive font
1674 bool hadAdaptiveFont = (mAdaptiveFontObject.get() != NULL);
1675
1676 // Get the requested font size (original size before adaptation)
1677 Variant requestedSizeVar = PEBLObjectBase::GetProperty("REQUESTEDFONTSIZE");
1678 int requestedSize = requestedSizeVar.GetInteger();
1679
1680 // If requestedFontSize is 0, it hasn't been set yet - use current font size
1681 if (requestedSize == 0) {
1682 requestedSize = GetPlatformFont()->GetFontSize();
1683 PEBLObjectBase::SetProperty("REQUESTEDFONTSIZE", Variant(requestedSize));
1684 }
1685
1686 // Iterate to find the right font size
1687 // Keep previous adaptive font in mIntermediateFonts during iteration
1688 int maxIterations = 20;
1689 int iteration = 0;
1690 bool needsAdaptation = true;
1691
1692 while (iteration < maxIterations && needsAdaptation) {
1693 // Calculate line breaks with current font
1694 FindBreaks();
1695
1696 // Check if text currently fits
1697 Variant textCompleteVar = PEBLObjectBase::GetProperty("TEXTCOMPLETE");
1698 bool textComplete = textCompleteVar.GetInteger() != 0;
1699
1700 if (textComplete) {
1701 // Text fits - stop iteration
1702 needsAdaptation = false;
1703 break;
1704 }
1705
1706 // Text doesn't fit - calculate target font size
1707 int minFontSize = 8;
1708 int currentFontSize = GetPlatformFont()->GetFontSize();
1709 int targetSize = currentFontSize;
1710
1711 // Text doesn't fit (TEXTCOMPLETE=0), so we need to shrink the font
1712 // Reduce by 10% (minimum 1 point) each iteration
1713 {
1714 int reduction = std::max(currentFontSize / 10, 1);
1715 targetSize = std::max(currentFontSize - reduction, minFontSize);
1716 }
1717
1718 // Safety: ensure we're actually shrinking, never growing
1719 if (targetSize >= currentFontSize) {
1720 targetSize = std::max(currentFontSize - 1, minFontSize);
1721 }
1722
1723 // Create new font if we calculated a different size
1724 if (targetSize != currentFontSize && targetSize >= minFontSize) {
1725 std::string fontFileName = GetPlatformFont()->GetFontFileName();
1726 int fontStyle = GetPlatformFont()->GetFontStyle();
1727 PColor fontColor = GetPlatformFont()->GetFontColor();
1728 PColor bgColor = GetPlatformFont()->GetBackgroundColor();
1729 bool antiAliased = GetPlatformFont()->GetAntiAliased();
1730
1731 // Keep previous adaptive font alive during iteration
1732 if (mAdaptiveFontObject.get()) {
1733 mIntermediateFonts.push_back(mAdaptiveFontObject);
1734 }
1735
1736 // Create new font and immediately wrap in counted_ptr
1737 PlatformFont* newFont = new PlatformFont(fontFileName, fontStyle, targetSize,
1738 fontColor, bgColor, antiAliased);
1739 counted_ptr<PEBLObjectBase> newFontPtr(newFont);
1740
1741 // Set as new adaptive font
1742 mAdaptiveFontObject = newFontPtr;
1743
1744 // Update widget background color
1745 PWidget::SetBackgroundColor(GetPlatformFont()->GetBackgroundColor());
1746 } else {
1747 needsAdaptation = false;
1748 }
1749
1750 iteration++;
1751 }
1752
1753 // If we created an adaptive font, make sure it's set
1754 if (mAdaptiveFontObject.get()) {
1755 mChanged = true;
1756 }
1757
1758 // Clear intermediate fonts AFTER rendering is complete
1759 // This happens later in the function after RenderText() is called
1760 }
1761
1762 mChanged = true;
1763 }
1764
1766 {
1767 RenderText();
1768 }
1769
1770 // Don't clear intermediate fonts - let them persist for the textbox's lifetime
1771 // They will be cleaned up automatically when the textbox destructor runs
1772 // This avoids triggering destructor cascades during drawing
1773
1774 mCursorChanged = false;
1775
1776
1777 bool ret = PlatformWidget::Draw();
1778
1779 if(mEditable&false)
1780 {
1781 DrawCursor();
1782 }
1783
1784
1785 return ret;
1786}
virtual bool SetProperty(std::string name, Variant v)
Variant GetProperty(std::string) const
virtual PColor GetBackgroundColor() const
Definition PFont.cpp:296
virtual int GetFontStyle() const
Definition PFont.h:84
virtual PColor GetFontColor() const
Definition PFont.cpp:289
virtual std::string GetFontFileName() const
Definition PFont.h:83
virtual bool GetAntiAliased() const
Definition PFont.h:88
virtual int GetFontSize() const
Definition PFont.h:85
bool mCursorChanged
Definition PTextBox.h:92
bool mEditable
Definition PTextBox.h:90
virtual void SetBackgroundColor(const PColor &color)
Definition PWidget.cpp:287
virtual PColor GetBackgroundColor()
Definition PWidget.h:92
void ClearChanged()
Clear all changed flags.
virtual bool RenderText()
virtual bool Draw()
This method initiates everything needed to display the main window
pInt GetInteger() const
Definition Variant.cpp:997
X * get() const
Definition rc_ptrs.h:110

References PlatformFont::ClearChanged(), PlatformWidget::Draw(), counted_ptr< X >::get(), PFont::GetAntiAliased(), PWidget::GetBackgroundColor(), PFont::GetBackgroundColor(), PFont::GetFontColor(), PFont::GetFontFileName(), PFont::GetFontSize(), PFont::GetFontStyle(), Variant::GetInteger(), PEBLObjectBase::GetProperty(), PTextObject::mChanged, PTextBox::mCursorChanged, PTextBox::mEditable, NULL, RenderText(), PWidget::SetBackgroundColor(), and PEBLObjectBase::SetProperty().

◆ Draw() [2/2]

virtual bool PlatformTextBox::Draw ( )
virtual

This method initiates everything needed to display the main window

Reimplemented from PlatformWidget.

◆ FindCursorPosition() [1/2]

int PlatformTextBox::FindCursorPosition ( long int  x,
long int  y 
)
virtual

Given an x,y position, this will return an integer specifying the character in mText before which the cursor should be n. But, the text may be UTF-8, so an particular character may be several bytes wide so we need to take care to compute cursor position correctly. Cursor position should be related to the byte is the string, but it should not allow half-byte character positions.

Definition at line 1454 of file sdl/PlatformTextBox.cpp.

1455{
1456
1457
1458 if(mText.length()==0)
1459 {
1460 return 0;
1461 }
1462
1463 //Find the height of a line.
1464 int height = GetPlatformFont()->GetTextHeight(mText);
1465
1466 if(y > mHeight) y = mHeight;
1467 if(y < 0) y = 0;
1468
1469 //The line will just be y / height, rounded down
1470 unsigned long int linenum = y / height; //this is 0-based.
1471
1472
1473 //Change the line number to the last one if it is too large.
1474 //The last element of mBreaks is the 'end' of the text; not really a break for
1475 //our purposes.
1476
1477 if(linenum > mBreaks.size())
1478 linenum = mBreaks.size();
1479
1480
1481 //find the starting character on the line we care about.
1482 int startchar;
1483 if(linenum==0)
1484 startchar = 0;
1485 else
1486 startchar = mBreaks[linenum-1];
1487
1488
1489
1490 if(startchar >= mBreaks[mBreaks.size()-1])
1491 {
1492 return startchar;
1493 }
1494
1495 //find the length in bytes of the current line:
1496 int length = mBreaks[linenum] - startchar;
1497
1498 // Get the line text to check for RTL
1499 std::string line_text = mText.substr(startchar, length);
1500
1501 // For right-justified text, x is the visual position from left edge of textbox
1502 // We need to convert it to what GetPosition() expects
1503 unsigned int x_adjusted = x;
1504 if (is_line_right_justified(line_text, mJustify)) {
1505 // Get line width to calculate where text starts
1506 int line_width = GetPlatformFont()->GetTextWidth(line_text);
1507 int text_start_x = mWidth - line_width; // Right justification offset
1508
1509 if ((int)x >= text_start_x) {
1510 // Click is within the text area
1511 // For RTL text, GetPosition() expects x from LEFT edge of text,
1512 // but RTL text renders right-to-left, so we need to flip:
1513 // Visual position from left of text = (x - text_start_x)
1514 // For RTL, we need position from RIGHT = line_width - (x - text_start_x)
1515 if (has_rtl_text(line_text)) {
1516 x_adjusted = line_width - ((int)x - text_start_x);
1517 } else {
1518 // Explicit RIGHT justification with LTR text
1519 x_adjusted = (int)x - text_start_x;
1520 }
1521 } else {
1522 // Click is to the left of the text (in the padding area)
1523 // For RTL, this means beginning of text (which is visually on right)
1524 // For LTR right-justified, this means before text starts
1525 x_adjusted = has_rtl_text(line_text) ? line_width : 0;
1526 }
1527 }
1528
1529 int charnum = GetPlatformFont()->GetPosition(line_text, x_adjusted);
1530
1531 //finally, if the current cursor position is a non-printing character (i.e. a carriage return)
1532 //back up one
1533
1534 if(!AtPrintableCharacter(charnum + startchar -1))
1535 {
1536
1537 if(charnum + startchar > 0)
1538 charnum--;
1539 }
1540
1541
1542 return charnum + startchar;
1543}
Variant mJustify
Definition PTextBox.h:94
virtual bool AtPrintableCharacter(unsigned long int x)
Definition PTextBox.cpp:424
unsigned int GetTextHeight(const std::string &text)
unsigned int GetTextWidth(const std::string &text)
unsigned int GetPosition(const std::string &text, unsigned int x)
std::vector< int > mBreaks

References PTextBox::AtPrintableCharacter(), PlatformFont::GetPosition(), PlatformFont::GetTextHeight(), PlatformFont::GetTextWidth(), mBreaks, PWidget::mHeight, PTextBox::mJustify, PTextObject::mText, and PWidget::mWidth.

Referenced by PEBLEnvironment::GetTextBoxCursorFromClick(), and HandleKeyPress().

◆ FindCursorPosition() [2/2]

virtual int PlatformTextBox::FindCursorPosition ( long int  x,
long int  y 
)
inlinevirtual

Definition at line 42 of file validator/PlatformTextBox.h.

42{ return 0; } // Stub for validator

◆ GetFont()

virtual counted_ptr< PEBLObjectBase > PlatformTextBox::GetFont ( ) const
inlinevirtual

Definition at line 78 of file sdl/PlatformTextBox.h.

78 {
79 return mAdaptiveFontObject.get() ? mAdaptiveFontObject : mFontObject;
80 }

References counted_ptr< X >::get().

Referenced by PlatformTextBox().

◆ GetLineBreaks() [1/2]

Variant PlatformTextBox::GetLineBreaks ( )

Definition at line 1952 of file sdl/PlatformTextBox.cpp.

1953{
1954 //Not sure about this, but let's not refind line breaks when this is called--just get
1955 //whatever has been calculated.
1956
1957 std::vector<int>::iterator i = mBreaks.begin();
1958
1959 PList * outlist = new PList();
1960 while(i != mBreaks.end())
1961 {
1962 outlist->PushBack(*i);
1963 i++;
1964 }
1965
1966
1968
1969 PComplexData * PCD =(new PComplexData(newList2));
1970 Variant tmp = Variant(PCD);
1971 delete PCD;
1972 PCD=NULL;
1973 return tmp;
1974
1975}
Definition PList.h:45
void PushBack(const Variant &v)
Definition PList.cpp:149

References mBreaks, NULL, and PList::PushBack().

Referenced by PEBLObjects::GetLineBreaks().

◆ GetLineBreaks() [2/2]

virtual Variant PlatformTextBox::GetLineBreaks ( )
inlinevirtual

Definition at line 43 of file validator/PlatformTextBox.h.

43{ return Variant(0); } // Stub for validator

◆ GetProperty()

Variant PlatformTextBox::GetProperty ( std::string  name) const
virtual

Reimplemented from PWidget.

Definition at line 655 of file sdl/PlatformTextBox.cpp.

656{
657 if(name == "NUMTEXTLINES")
658 {
659 return Variant((int)mBreaks.size());
660 }
661 else
662 {
663 return PTextBox::GetProperty(name);
664 }
665}
virtual Variant GetProperty(std::string) const
Definition PTextBox.cpp:154

References PTextBox::GetProperty(), and mBreaks.

◆ HandleKeyPress()

void PlatformTextBox::HandleKeyPress ( int  keycode,
int  modkeys,
Uint16  unicode 
)
virtual

Reimplemented from PTextBox.

Definition at line 1791 of file sdl/PlatformTextBox.cpp.

1792{
1793#if 0
1794 cerr << "handling keypress in PlatformTextBox: " << keycode << endl;
1795 cerr << "(" << PEBL_KEYCODE_RETURN << "|" << PEBL_KEYCODE_RETURN2 << "|" << PEBL_KEYCODE_KP_ENTER << ")"<< std::endl;
1796 cerr << "PEBL_KEYCODE_RIGHT:" << PEBL_KEYCODE_RIGHT << std::endl;
1797 cerr << "PEBL_KEYCODE_LEFT:" << PEBL_KEYCODE_LEFT << std::endl;
1798#endif
1799
1800 switch(keycode)
1801 {
1802 case PEBL_KEYCODE_UP:
1803 case PEBL_KEYCODE_DOWN:
1804 {
1805 int change;
1806 if(keycode == PEBL_KEYCODE_UP) change = -1;
1807 else change = 1;
1808
1809 //Find x and y of position.
1810 int x = 0;
1811 int y = 0;
1812
1813 int height=GetPlatformFont()->GetTextHeight(mText);
1814 unsigned int i = 0;
1815 int linestart = 0;
1816
1817
1818 while(i < mBreaks.size())
1819 {
1820 if(mBreaks[i] > mCursorPos)
1821 {
1822 y = i * height;
1823
1824 // Calculate x position (visual position from left edge of textbox)
1825 std::string text_before_cursor = mText.substr(linestart, mCursorPos - linestart);
1826
1827 // Get the full line to check justification
1828 int line_end = mBreaks[i];
1829 std::string full_line = mText.substr(linestart, line_end - linestart);
1830
1831 if (is_line_right_justified(full_line, mJustify)) {
1832 // Right-justified: text starts at (width - line_width)
1833 // Cursor is at distance (line_width - text_before_cursor_width) from right edge of text
1834 // Visual x = text_start + (line_width - text_before_cursor_width)
1835 // = (width - line_width) + (line_width - text_before_cursor_width)
1836 // = width - text_before_cursor_width
1837 int text_before_cursor_width = GetPlatformFont()->GetTextWidth(text_before_cursor);
1838 x = mWidth - text_before_cursor_width;
1839 } else {
1840 // Left-justified: x is simply width of text before cursor
1841 x = GetPlatformFont()->GetTextWidth(text_before_cursor);
1842 }
1843 break;
1844 }
1845 linestart = mBreaks[i];
1846 i++;
1847 }
1848
1849
1850 mCursorPos = FindCursorPosition(x, y + change * height);
1851 mCursorChanged = true;
1852 break;
1853 }
1857 {
1858
1859 std::string lb = std::string() + (char(10));
1860
1861 InsertText(lb);
1862 //mCursorPos++;
1863 if(mCursorPos > (int) (mText.length()))
1864 mCursorPos = mText.length();
1865
1866 }
1867 break;
1869
1870 DeleteText(1);
1871 break;
1873
1874 DeleteText(-1);
1875 break;
1876
1877 case PEBL_KEYCODE_LEFT:
1878 case PEBL_KEYCODE_RIGHT:
1879 {
1880 // For RTL text, LEFT/RIGHT arrows should move in visual direction, not logical
1881 // Find which line the cursor is on to check if it's RTL
1882 bool isRTLLine = false;
1883
1884 if (mBreaks.size() > 0 && mText.length() > 0) {
1885 unsigned int i = 0;
1886 int linestart = 0;
1887
1888 while(i < mBreaks.size()) {
1889 if(mBreaks[i] >= mCursorPos) {
1890 // Found the current line
1891 int line_end = mBreaks[i];
1892 std::string current_line = mText.substr(linestart, line_end - linestart);
1893 isRTLLine = has_rtl_text(current_line);
1894 break;
1895 }
1896 linestart = mBreaks[i];
1897 i++;
1898 }
1899 }
1900
1901 // In RTL text, swap the behavior:
1902 // - LEFT arrow moves visually left (logically forward) = IncrementCursor
1903 // - RIGHT arrow moves visually right (logically backward) = DecrementCursor
1904 if (isRTLLine) {
1905 if (keycode == PEBL_KEYCODE_LEFT) {
1907 } else {
1909 }
1910 } else {
1911 // LTR text: normal behavior
1912 if (keycode == PEBL_KEYCODE_LEFT) {
1914 } else {
1916 }
1917 }
1918 }
1919 break;
1920
1921
1922 //case PEBL_KEYCODE_BACKSLASH:
1923 //InsertText("\\");
1924 //cerr << "backslash\n";
1925 // InsertText(PEBLUtility::TranslateKeycode((PEBL_Keycode)keycode, modkeys));
1926 //break;
1927
1928 default:
1929 //cerr << "----------------------\n" << keycode << endl;
1930 //cerr << "["<< (PEBLUtility::TranslateKeyCode(PEBLKey(keycode), modkeys))<<"]"<<endl;
1931 //cerr << "----------------------\n";
1932
1933
1934 // InsertText(SDL_GetKeyName(keycode));
1935 ;
1936 }
1937 mCursorChanged=true;
1938 //PTextBox::HandleKeyPress(keycode, modkeys, unicode);
1939}
@ PEBL_KEYCODE_RETURN2
Definition PKeyboard.h:231
@ PEBL_KEYCODE_DELETE
Definition PKeyboard.h:171
@ PEBL_KEYCODE_DOWN
Definition PKeyboard.h:176
@ PEBL_KEYCODE_KP_ENTER
Definition PKeyboard.h:183
@ PEBL_KEYCODE_LEFT
Definition PKeyboard.h:175
@ PEBL_KEYCODE_RIGHT
Definition PKeyboard.h:174
@ PEBL_KEYCODE_BACKSPACE
Definition PKeyboard.h:82
@ PEBL_KEYCODE_RETURN
Definition PKeyboard.h:80
@ PEBL_KEYCODE_UP
Definition PKeyboard.h:177
virtual long unsigned int IncrementCursor()
Definition PTextBox.cpp:295
virtual void InsertText(const std::string character)
Definition PTextBox.cpp:189
virtual long unsigned int DecrementCursor()
Definition PTextBox.cpp:334
unsigned long int mCursorPos
Definition PTextBox.h:91
virtual void DeleteText(int length)
Definition PTextBox.cpp:210
virtual int FindCursorPosition(long int x, long int y)

References PTextBox::DecrementCursor(), PTextBox::DeleteText(), FindCursorPosition(), PlatformFont::GetTextHeight(), PlatformFont::GetTextWidth(), PTextBox::IncrementCursor(), PTextBox::InsertText(), mBreaks, PTextBox::mCursorChanged, PTextBox::mCursorPos, PTextBox::mJustify, PTextObject::mText, PWidget::mWidth, PEBL_KEYCODE_BACKSPACE, PEBL_KEYCODE_DELETE, PEBL_KEYCODE_DOWN, PEBL_KEYCODE_KP_ENTER, PEBL_KEYCODE_LEFT, PEBL_KEYCODE_RETURN, PEBL_KEYCODE_RETURN2, PEBL_KEYCODE_RIGHT, and PEBL_KEYCODE_UP.

Referenced by PEBLEnvironment::GetInput0().

◆ HandleTextInput()

void PlatformTextBox::HandleTextInput ( std::string  input)
virtual

Reimplemented from PTextBox.

Definition at line 1945 of file sdl/PlatformTextBox.cpp.

1946{
1947
1949}
virtual void HandleTextInput(std::string text)
Definition PTextBox.cpp:414

References PTextBox::HandleTextInput().

Referenced by PEBLEnvironment::GetInput0().

◆ ObjectName() [1/2]

virtual std::string PlatformTextBox::ObjectName ( ) const
inlinevirtual

Reimplemented from PWidget.

Definition at line 86 of file sdl/PlatformTextBox.h.

86{return "PlatformTextBox";} ;

◆ ObjectName() [2/2]

virtual std::string PlatformTextBox::ObjectName ( ) const
inlinevirtual

Reimplemented from PWidget.

Definition at line 41 of file validator/PlatformTextBox.h.

41{ return "PlatformTextBox (validator)"; }

◆ RenderText()

bool PlatformTextBox::RenderText ( )
virtual

This method should be called when the font is initialized or the text is changed. It will make the mSurface pointer hold the appropriate image.

Definition at line 190 of file sdl/PlatformTextBox.cpp.

191{
192
193 //free the memory if it is currently pointing at something.
194 //#ifdef SDL2_DELETE
195 if(mSurface) SDL_FreeSurface(mSurface);
196 //#endif
197
198 //create a new surface on which to render the text.
199
200#if SDL_BYTEORDER == SDL_BIG_ENDIAN
201
202 Uint32 rmask = 0xff000000;
203 Uint32 gmask = 0x00ff0000;
204 Uint32 bmask = 0x0000ff00;
205 Uint32 amask = 0x00000000;
206
207#else
208
209 Uint32 rmask = 0x000000ff;
210 Uint32 gmask = 0x0000ff00;
211 Uint32 bmask = 0x00ff0000;
212 Uint32 amask = 0x00000000;
213
214#endif
215
216 //we might get a Draw() command before the renderer is set,
217 //such as if the text is set before the object is added to a
218 //parent that has a renderer.
219
220
221 if(!mRenderer)
222 {
223 //cerr << "No renderer " << SDL_GetTicks() << endl;
224
225 return false;
226 }
227
228 //cerr << "creating new surface in platformtextbox::rendertext\n";
229
230 //Make a surface of the prescribed size.
231 mSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,
232 (int)mTextureWidth,
233 (int)mTextureHeight, 32,
234 rmask, gmask, bmask, amask);
235 if(!mSurface) PError::SignalFatalError("Surface not created in TextBox::RenderText.");
236
237 //cerr << "fillingbackground rec platformtextbox::rendertext\n";
238 //Fill the box with the background color of the font (from property system in case it was modified)
239 PColor bgcolor = GetPlatformFont()->GetBackgroundColor(); // Gets current color from font property system
240 SDL_FillRect(mSurface, NULL, SDL_MapRGBA(mSurface->format,
241 bgcolor.GetRed(),
242 bgcolor.GetGreen(),
243 bgcolor.GetBlue(),
244 bgcolor.GetAlpha()));
245
246
247 //First, find the height of the text when rendered with the font.
248 int height = GetPlatformFont()->GetTextHeight(mText);
249
250 //Now, go through the text letter by letter and word by word until it won't fit on a line any longer.
251 unsigned int linestart = 0;
252 unsigned int linelength = 0;
253 unsigned int totalheight = 0;
254
255 SDL_Surface * tmpSurface=NULL;
256 std::vector<int>::iterator i = mBreaks.begin();
257 linestart = 0;
258
259 //cerr << "Textbox: "<< mHeight << " " <<totalheight << endl;
260
261 // Check if formatted text mode is enabled
262 Variant formattedVar = PEBLObjectBase::GetProperty("FORMATTED");
263 bool isFormatted = (formattedVar.GetInteger() != 0);
264
265 // Parse formatted text once if needed
266 std::vector<FormatParser::FormatSegment> segments;
267 if (isFormatted) {
268 // Calculate character width for indent calculations
269 int charWidth = GetPlatformFont()->GetTextWidth("M"); // Use 'M' as average char width
270 segments = FormatParser::ParseFormattedText(mText, charWidth);
271 }
272
273 while(i != mBreaks.end() && totalheight < (unsigned int) mHeight)
274 {
275
276
277 //mBreaks holds the 'starting' positions of each line.
278 linelength = *i - linestart;
279 if(linelength>0)
280 {
281
282 SDL_Rect to;
283
284 // Auto-detect RTL for THIS LINE and adjust justification
285 // For formatted text, use stripped text for line extraction
286 std::string line_text;
287 if (isFormatted) {
288 line_text = mStrippedText.substr(linestart, linelength);
289 } else {
290 line_text = mText.substr(linestart, linelength);
291 }
292 bool isLineRTL = has_rtl_text(line_text);
293
294 // Determine effective justification: RTL overrides mJustify
295 Variant effectiveJustify;
296 if (isLineRTL) {
297 effectiveJustify = "RIGHT";
298 } else {
299 effectiveJustify = mJustify;
300 }
301
302 if (isFormatted) {
303 // Cache fonts for this line to avoid repeated creation/deletion
304 // Key: (style, size, color_as_int) -> Value: PlatformFont*
305 std::map<std::tuple<int, int, unsigned int>, PlatformFont*> fontCache;
306
307 // FIRST PASS: Find maximum ascent, total width, justification for baseline alignment
308 int maxAscent = 0;
309 int maxLineHeight = 0; // Track maximum font height on this line
310 unsigned int segmentTextPos = 0;
311 bool hasHorizontalRule = false;
312 int lineIndent = 0; // Track indent for this line
313 int totalLineWidth = 0; // Total width of all segments on this line
314 FormatParser::Justification lineJustification = FormatParser::JUSTIFY_NONE; // Line justification
315
316 // Get base font properties once
317 PlatformFont* baseFont = GetPlatformFont();
318 std::string fontFileName = baseFont->GetFontFileName();
319 int baseFontSize = baseFont->GetFontSize();
320 PColor baseFgColor = baseFont->GetFontColor();
321 PColor baseBgColor = baseFont->GetBackgroundColor();
322 bool antiAliased = baseFont->GetAntiAliased();
323
324 for (const FormatParser::FormatSegment& seg : segments) {
325 unsigned int segStart = segmentTextPos;
326 unsigned int segEnd = segmentTextPos + seg.text.length();
327
328 if (segEnd > linestart && segStart < linestart + linelength) {
329 // Check for horizontal rule
330 if (seg.isHorizontalRule) {
331 hasHorizontalRule = true;
332 }
333
334 // Track indent (accumulates across segments on same line)
335 if (seg.indentPixels > 0) {
336 lineIndent = seg.indentPixels;
337 }
338
339 // Track justification (use first non-NONE justification found on line)
340 if (lineJustification == FormatParser::JUSTIFY_NONE && seg.justification != FormatParser::JUSTIFY_NONE) {
341 lineJustification = seg.justification;
342 }
343
344 unsigned int overlapStart = std::max(segStart, (unsigned int)linestart);
345 unsigned int overlapEnd = std::min(segEnd, (unsigned int)(linestart + linelength));
346 std::string segmentText = seg.text.substr(overlapStart - segStart, overlapEnd - overlapStart);
347
348 if (!segmentText.empty()) {
349 int segStyle = seg.style;
350 // Calculate proportional size: sizeOverride is now a percentage (100 = base font)
351 int segSize = baseFontSize;
352 if (seg.hasSizeOverride) {
353 segSize = (baseFontSize * seg.sizeOverride) / 100;
354 // Sanity check: ensure size is reasonable
355 if (segSize < 1) segSize = 1;
356 if (segSize > 200) segSize = 200;
357 }
358 PColor segFgColor = seg.hasColorOverride ? seg.colorOverride : baseFgColor;
359
360 // Create cache key (color encoded as R*256*256 + G*256 + B)
361 unsigned int colorKey = segFgColor.GetRed() * 65536 +
362 segFgColor.GetGreen() * 256 +
363 segFgColor.GetBlue();
364 auto cacheKey = std::make_tuple(segStyle, segSize, colorKey);
365
366 // Get or create font
367 PlatformFont* renderFont;
368 auto it = fontCache.find(cacheKey);
369 if (it != fontCache.end()) {
370 renderFont = it->second;
371 } else {
372 renderFont = new PlatformFont(
373 fontFileName, segStyle, segSize,
374 segFgColor, baseBgColor, antiAliased);
375 fontCache[cacheKey] = renderFont;
376 }
377
378 // Get the ascent (height above baseline) for this font
379 int ascent = TTF_FontAscent(renderFont->GetTTFFont());
380 if (ascent > maxAscent) maxAscent = ascent;
381
382 // Get the full line height (ascent + descent) for this font
383 int lineHeight = TTF_FontHeight(renderFont->GetTTFFont());
384 if (lineHeight > maxLineHeight) maxLineHeight = lineHeight;
385
386 // Calculate width for this segment
387 totalLineWidth += renderFont->GetTextWidth(segmentText);
388 }
389 }
390 segmentTextPos += seg.text.length();
391 }
392
393 // Calculate justification offset
394 // Use HTML alignment if specified, otherwise fall back to
395 // the textbox .justify property (mJustify)
396 int justifyOffset = 0;
397 if (lineJustification == FormatParser::JUSTIFY_CENTER) {
398 justifyOffset = (mWidth - totalLineWidth) / 2;
399 } else if (lineJustification == FormatParser::JUSTIFY_RIGHT) {
400 justifyOffset = mWidth - totalLineWidth;
401 } else if (lineJustification == FormatParser::JUSTIFY_NONE) {
402 // No HTML alignment — fall back to .justify property
403 if (effectiveJustify == "CENTER") {
404 justifyOffset = (mWidth - totalLineWidth) / 2;
405 } else if (is_line_right_justified(line_text, effectiveJustify)) {
406 justifyOffset = mWidth - totalLineWidth;
407 }
408 }
409
410 // SECOND PASS: Render segments with baseline alignment and justification
411 int xOffset = justifyOffset; // Start with justification offset
412 segmentTextPos = 0;
413
414 // Render horizontal rule if present
415 if (hasHorizontalRule) {
416 // Draw a horizontal line across the textbox width
417 PColor lineColor = GetPlatformFont()->GetFontColor();
418 int lineY = static_cast<int>(totalheight) + maxAscent / 2;
419 int lineWidth = mWidth - (lineIndent * 2); // Leave margins
420
421 // Draw horizontal line (simple rectangle)
422 SDL_Rect hrRect = {lineIndent, lineY, lineWidth, 2};
423 SDL_FillRect(mSurface, &hrRect,
424 SDL_MapRGBA(mSurface->format,
425 lineColor.GetRed(),
426 lineColor.GetGreen(),
427 lineColor.GetBlue(),
428 255));
429 }
430
431 for (const FormatParser::FormatSegment& seg : segments) {
432 unsigned int segStart = segmentTextPos;
433 unsigned int segEnd = segmentTextPos + seg.text.length();
434
435 if (segEnd > linestart && segStart < linestart + linelength) {
436 unsigned int overlapStart = std::max(segStart, (unsigned int)linestart);
437 unsigned int overlapEnd = std::min(segEnd, (unsigned int)(linestart + linelength));
438
439 std::string segmentText = seg.text.substr(
440 overlapStart - segStart,
441 overlapEnd - overlapStart);
442
443 if (!segmentText.empty()) {
444 // If this segment has an indent, use it as absolute x-position (but only if greater than current xOffset)
445 if (seg.indentPixels > xOffset) {
446 xOffset = seg.indentPixels;
447 }
448
449 int segStyle = seg.style;
450 // Calculate proportional size: sizeOverride is now a percentage (100 = base font)
451 int segSize = baseFontSize;
452 if (seg.hasSizeOverride) {
453 segSize = (baseFontSize * seg.sizeOverride) / 100;
454 // Sanity check: ensure size is reasonable
455 if (segSize < 1) segSize = 1;
456 if (segSize > 200) segSize = 200;
457 }
458 PColor segFgColor = seg.hasColorOverride ? seg.colorOverride : baseFgColor;
459
460 // Create cache key (same as first pass)
461 unsigned int colorKey = segFgColor.GetRed() * 65536 +
462 segFgColor.GetGreen() * 256 +
463 segFgColor.GetBlue();
464 auto cacheKey = std::make_tuple(segStyle, segSize, colorKey);
465
466 // Get font from cache (should always exist since we created it in first pass)
467 PlatformFont* renderFont = fontCache[cacheKey];
468
469 tmpSurface = renderFont->RenderText(segmentText.c_str());
470
471 // Get ascent for this specific font
472 int thisAscent = TTF_FontAscent(renderFont->GetTTFFont());
473
474 // Calculate y-offset to align baseline with max baseline
475 int yOffset = maxAscent - thisAscent;
476
477 // Position segment with baseline alignment
478 SDL_Rect segRect = {xOffset, static_cast<int>(totalheight) + yOffset,
479 tmpSurface->w, tmpSurface->h};
480
481 SDL_BlitSurface(tmpSurface, NULL, mSurface, &segRect);
482 SDL_FreeSurface(tmpSurface);
483
484 xOffset += segRect.w;
485 }
486 }
487
488 segmentTextPos += seg.text.length();
489 }
490
491 // Clean up cached fonts for this line
492 for (auto& pair : fontCache) {
493 delete pair.second;
494 }
495
496 // For formatted text, use the maximum line height found on this line
497 // instead of the base font height
498 totalheight += maxLineHeight;
499 } else {
500 // Normal (non-formatted) rendering
501 if(effectiveJustify == "RIGHT")
502 {
503 //right flush
504 tmpSurface = GetPlatformFont()->RenderText(line_text.c_str());
505 SDL_Rect tmprect = {mSurface->w - tmpSurface->w,
506 static_cast<int>(totalheight),
507 tmpSurface->w,tmpSurface->h};
508 to = tmprect;
509 }
510 else if (effectiveJustify == "CENTER"){
511 //centered
512 tmpSurface = GetPlatformFont()->RenderText(line_text.c_str());
513 int xval = (mSurface->w - tmpSurface->w)/2;
514 SDL_Rect tmprect = {xval,static_cast<int>(totalheight),
515 tmpSurface->w,tmpSurface->h};
516 to = tmprect;
517 }
518 else{
519 // LEFT justification (default)
520 tmpSurface = GetPlatformFont()->RenderText(line_text.c_str());
521 SDL_Rect tmprect = {0,static_cast<int>(totalheight),tmpSurface->w,tmpSurface->h};
522 to = tmprect;
523 }
524
525
526 if(0)
527 {
528 //This was originally used for international right-to-left font layout, but
529 //it never worked.
530 std::string tmptext = mText.substr(linestart,linelength);
531
532 //
533 std::string rtext = PEBLUtility::strrev_utf8(tmptext);
534
535
536
537 //Re-render the text using the associated font.
538 tmpSurface = GetPlatformFont()->RenderText(rtext.c_str());
539
540
541 SDL_Rect tmprect = {(mSurface->w - tmpSurface->w),static_cast<int>(totalheight),
542 tmpSurface->w, tmpSurface->h};
543 to = tmprect;
544
545 }
546
547
548 SDL_BlitSurface(tmpSurface, NULL, mSurface,&to);
549 SDL_FreeSurface(tmpSurface);
550
551 // For normal text, use the base font height
552 totalheight += height;
553 }
554 }
555 else
556 {
557 // No line content, still need to increment height for empty lines
558 totalheight += height;
559 }
560
561 linestart = *i;
562 i++;
563
564 }
565
566 if(mTexture)
567 {
568
569
570 SDL_DestroyTexture(mTexture);
571 mTexture = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET,
572 (int)mTextureWidth,
573 (int)mTextureHeight);
574 // Enable best quality filtering (anisotropic) for zoomed textures
575 SDL_SetTextureScaleMode(mTexture, SDL_ScaleModeBest);
576 SDL_SetTextureBlendMode(mTexture, SDL_BLENDMODE_BLEND);
577 }
578 else
579 {
580
581 mTexture = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET,
582 (int)mTextureWidth,(int)mTextureHeight);
583 // Enable best quality filtering (anisotropic) for zoomed textures
584 SDL_SetTextureScaleMode(mTexture, SDL_ScaleModeBest);
585 SDL_SetTextureBlendMode(mTexture, SDL_BLENDMODE_BLEND);
586
587 }
588
589
590
591
592 //This will work except for drawing the cursor line on it. instead, create
593 //a texture from the surface, then copy it to mtexture.
594 //mTexture = SDL_CreateTextureFromSurface(mRenderer, mSurface);
595
596 SDL_Texture * tmp = SDL_CreateTextureFromSurface(mRenderer, mSurface);
597 SDL_FreeSurface(mSurface);
598 mSurface = NULL;
599 SDL_SetRenderTarget(mRenderer, mTexture);
600 SDL_RenderCopy(mRenderer, tmp, NULL, NULL);
601 SDL_SetRenderTarget(mRenderer,NULL);
602 SDL_DestroyTexture(tmp);
603
604 if(mEditable)
605 {
606 DrawCursor();
607 }
608
609
610 //If mTexture is null, then rendering failed.
611 if(mTexture)
612 {
613
614 mChanged = false;
615 return true;
616 }
617 else
618 {
619
620 mChanged = true;
621 return false;
622 }
623}
int GetRed() const
Definition PColor.cpp:226
int GetAlpha() const
Definition PColor.cpp:229
int GetBlue() const
Definition PColor.cpp:228
int GetGreen() const
Definition PColor.cpp:227
SDL_Surface * RenderText(const std::string &text)
This takes care of all the busy work of rendering the text.
TTF_Font * GetTTFFont() const
Justification
Justification types for paragraph-level alignment.
std::vector< FormatSegment > ParseFormattedText(const std::string &input, int charWidth)
Parse formatted text into segments.
void strrev_utf8(char *p)
void SignalFatalError(const std::string &message)

References PColor::GetAlpha(), PFont::GetAntiAliased(), PFont::GetBackgroundColor(), PColor::GetBlue(), PFont::GetFontColor(), PFont::GetFontFileName(), PFont::GetFontSize(), PColor::GetGreen(), Variant::GetInteger(), PEBLObjectBase::GetProperty(), PColor::GetRed(), PlatformFont::GetTextHeight(), PlatformFont::GetTextWidth(), PlatformFont::GetTTFFont(), FormatParser::JUSTIFY_CENTER, FormatParser::JUSTIFY_NONE, FormatParser::JUSTIFY_RIGHT, mBreaks, PTextObject::mChanged, PTextBox::mEditable, PWidget::mHeight, PTextBox::mJustify, PlatformWidget::mRenderer, PlatformWidget::mSurface, PTextObject::mText, PlatformWidget::mTexture, PlatformWidget::mTextureHeight, PlatformWidget::mTextureWidth, PWidget::mWidth, NULL, FormatParser::ParseFormattedText(), PlatformFont::RenderText(), PError::SignalFatalError(), and PEBLUtility::strrev_utf8().

Referenced by Draw().

◆ SendToStream() [1/2]

std::ostream & PlatformTextBox::SendToStream ( std::ostream &  out) const
protectedvirtual

An inheritable printing class used by PEBLObjectBase::operator<<.

Reimplemented from PlatformWidget.

Definition at line 44 of file validator/PlatformTextBox.cpp.

44 {
45 out << "PlatformTextBox (validator)";
46 return out;
47}

◆ SendToStream() [2/2]

virtual std::ostream & PlatformTextBox::SendToStream ( std::ostream &  out) const
protectedvirtual

An inheritable printing class used by PEBLObjectBase::operator<<.

Reimplemented from PlatformWidget.

◆ SetEditable()

void PlatformTextBox::SetEditable ( bool  val)
virtual

Reimplemented from PTextBox.

Definition at line 739 of file sdl/PlatformTextBox.cpp.

740{
741 // Check if this is a formatted textbox
742 Variant formattedVar = PEBLObjectBase::GetProperty("FORMATTED");
743 bool isFormatted = (formattedVar.GetInteger() != 0);
744
745 if (val && isFormatted) {
746 // Disable formatted mode to allow editing of raw markdown text
747 // Tags will become visible as literal text for editing
748 std::cerr << "INFO: Disabling formatted mode for editing." << std::endl;
749 std::cerr << " Formatting tags will be visible as text and can be edited directly." << std::endl;
750
751 PEBLObjectBase::SetProperty("FORMATTED", Variant(0));
752 mChanged = true; // Force re-render to show raw tags
753 }
754
755 // Call parent implementation
757
758 // When making a textbox editable, position cursor at end of text
759 // This works for all justifications - the rendering code handles visual positioning
760 if (val) {
761 mCursorPos = mText.length();
762 mCursorChanged = true;
763 }
764}
virtual void SetEditable(bool val)
Definition PTextBox.h:61

References Variant::GetInteger(), PEBLObjectBase::GetProperty(), PTextObject::mChanged, PTextBox::mCursorChanged, PTextBox::mCursorPos, PTextObject::mText, PTextBox::SetEditable(), and PEBLObjectBase::SetProperty().

Referenced by PEBLEnvironment::GetInput0(), and PEBLObjects::SetEditable().

◆ SetFont() [1/2]

void PlatformTextBox::SetFont ( counted_ptr< PEBLObjectBase font)
virtual

Definition at line 691 of file sdl/PlatformTextBox.cpp.

692{
693
694 mFontObject = font;
695
696 // Update the FONT property so nested access works correctly
697 PComplexData * pcd = new PComplexData(mFontObject);
699 delete pcd;
700
701 // Set requestedFontSize when font is set (needed for adaptive textbox scaling)
702 // Only set it if it hasn't been set before (is 0)
703 Variant currentRequestedSize = PEBLObjectBase::GetProperty("REQUESTEDFONTSIZE");
704 if (currentRequestedSize.GetInteger() == 0) {
705 int fontSize = GetPlatformFont()->GetFontSize();
706 PEBLObjectBase::SetProperty("REQUESTEDFONTSIZE", Variant(fontSize));
707 }
708
710 mChanged = true;
711 //Re-render the text onto mSurface
712 //if(!RenderText()) cerr << "Unable to render text.\n";
713
714}

References PWidget::GetBackgroundColor(), PFont::GetFontSize(), Variant::GetInteger(), PEBLObjectBase::GetProperty(), PTextObject::mChanged, PWidget::SetBackgroundColor(), and PEBLObjectBase::SetProperty().

Referenced by PlatformTextBox(), PEBLObjects::SetFont(), and SetProperty().

◆ SetFont() [2/2]

virtual void PlatformTextBox::SetFont ( counted_ptr< PEBLObjectBase font)
inlinevirtual

Definition at line 44 of file validator/PlatformTextBox.h.

44{} // Stub for validator

◆ SetHeight()

void PlatformTextBox::SetHeight ( int  h)
virtual

Reimplemented from PTextBox.

Definition at line 669 of file sdl/PlatformTextBox.cpp.

670{
671 mTextureHeight = h;
673
674 // CRITICAL: Clear cached stripped text when height changes
675 // This ensures FindBreaksFormatted() recalculates line breaks with new height
676 mStrippedText.clear();
677}
virtual void SetHeight(int h)
Definition PTextBox.cpp:367

References PlatformWidget::mTextureHeight, and PTextBox::SetHeight().

Referenced by SetProperty().

◆ SetPosition()

virtual void PlatformTextBox::SetPosition ( pInt  x,
pInt  y 
)
inlinevirtual

This sets the widget's position on its parent widget.

Sets the location of the upper left-hand corner of the image on the parent widget; unless overridden

Reimplemented from PWidget.

Definition at line 58 of file validator/PlatformTextBox.h.

58{ PTextBox::SetPosition(x, y); }
virtual void SetPosition(pInt x, pInt y)
This sets the widget's position on its parent widget.
Definition PWidget.cpp:220

References PWidget::SetPosition().

Referenced by PEBLObjects::MakeTextBox().

◆ SetProperty() [1/2]

virtual bool PlatformTextBox::SetProperty ( std::string  name,
Variant  v 
)
inlinevirtual

Reimplemented from PWidget.

Definition at line 47 of file validator/PlatformTextBox.h.

47 {
48 return PTextBox::SetProperty(name, v);
49 }
virtual bool SetProperty(std::string, Variant v)
Definition PTextBox.cpp:124

References PTextBox::SetProperty().

◆ SetProperty() [2/2]

bool PlatformTextBox::SetProperty ( std::string  name,
Variant  v 
)
virtual

Reimplemented from PWidget.

Definition at line 626 of file sdl/PlatformTextBox.cpp.

627{
628
629 if(name == "TEXT")
630 {
631 SetText(v);
632 }
633 else if(PTextBox::SetProperty(name,v))
634 {
635 // If we set it at higher level, don't worry.
636 // This includes FORMATTED property which is handled in PTextBox
637 }
638 else if (name == "FONT")
639 {
641 }
642 else if(name=="WIDTH")
643 {
644 SetWidth(v);
645 }
646 else if(name=="HEIGHT")
647 {
648 SetHeight(v);
649 }
650 else return false;
651
652 return true;
653}
counted_ptr< PEBLObjectBase > GetObject() const
virtual void SetHeight(int h)
virtual void SetText(std::string text)
virtual void SetWidth(int w)
PComplexData * GetComplexData() const
Definition Variant.cpp:1299

References Variant::GetComplexData(), PComplexData::GetObject(), SetFont(), SetHeight(), PTextBox::SetProperty(), SetText(), and SetWidth().

Referenced by PEBLObjects::MakeTextBox().

◆ SetText()

void PlatformTextBox::SetText ( std::string  text)
virtual

Definition at line 718 of file sdl/PlatformTextBox.cpp.

719{
720
721
722 //Chain up to parent method.
724 mIsUTF8= utf8::is_valid(text.begin(),text.end());
725
726 //mCursorPos = 0;
727 mCursorChanged = true;
728 mChanged = true;
729
730 // Don't call Draw() here - it will be called when the object is actually drawn
731 // Calling Draw() during SetText() can cause crashes if the renderer isn't ready
732 // or if this is called during object construction/destruction
733
734 //Re-render the text onto mSurface
735 // if(!RenderText()) cerr << "Unable to render text.\n";
736
737}
virtual void SetText(const std::string &text)

References PTextObject::mChanged, PTextBox::mCursorChanged, and PTextObject::SetText().

Referenced by SetProperty(), and PEBLObjects::SetText().

◆ SetWidth()

void PlatformTextBox::SetWidth ( int  w)
virtual

Reimplemented from PTextBox.

Definition at line 679 of file sdl/PlatformTextBox.cpp.

680{
681 mTextureWidth = w;
683
684 // CRITICAL: Clear cached stripped text when width changes
685 // This forces FindBreaksFormatted() to recalculate line breaks with new width
686 // Without this, changing width after textbox creation causes incorrect line wrapping
687 mStrippedText.clear();
688}
virtual void SetWidth(int w)
Definition PTextBox.cpp:373

References PlatformWidget::mTextureWidth, and PTextBox::SetWidth().

Referenced by SetProperty().

◆ ValidateProperty() [1/2]

virtual ObjectValidationError PlatformTextBox::ValidateProperty ( std::string  name) const
inlinevirtual

Reimplemented from PWidget.

Definition at line 53 of file validator/PlatformTextBox.h.

53 {
54 return PTextBox::ValidateProperty(name);
55 }
virtual ObjectValidationError ValidateProperty(std::string, Variant v) const
Definition PTextBox.cpp:160

References PTextBox::ValidateProperty().

◆ ValidateProperty() [2/2]

virtual ObjectValidationError PlatformTextBox::ValidateProperty ( std::string  name,
Variant  v 
) const
inlinevirtual

Reimplemented from PWidget.

Definition at line 50 of file validator/PlatformTextBox.h.

50 {
51 return PTextBox::ValidateProperty(name, v);
52 }

References PTextBox::ValidateProperty().

Member Data Documentation

◆ mBreaks

std::vector<int> PlatformTextBox::mBreaks
protected

The documentation for this class was generated from the following files: