30 const char *Edit::CursorRepresentation =
"\xC2\xA6";
34 inline bool IsUtf8ContinuationByte(
char c)
36 return (c & 0xC0) == 0x80;
38 inline bool IsUtf8StartByte(
char c)
40 return (c & 0xC0) == 0xC0;
47 Edit::Edit(
const C4Rect &rtBounds,
bool fFocusEdit) :
Control(rtBounds), iCursorPos(0), iSelectionStart(0), iSelectionEnd(0), fLeftBtnDown(false)
68 pKeyCursorBack = RegisterCursorOp(COP_BACK , K_BACK ,
"GUIEditCursorBack", eKeyPrio);
69 pKeyCursorDel = RegisterCursorOp(COP_DELETE, K_DELETE,
"GUIEditCursorDel",eKeyPrio);
70 pKeyCursorLeft = RegisterCursorOp(COP_LEFT , K_LEFT ,
"GUIEditCursorLeft",eKeyPrio);
71 pKeyCursorRight = RegisterCursorOp(COP_RIGHT , K_RIGHT ,
"GUIEditCursorRight", eKeyPrio);
72 pKeyCursorHome = RegisterCursorOp(COP_HOME , K_HOME ,
"GUIEditCursorHome", eKeyPrio);
73 pKeyCursorEnd = RegisterCursorOp(COP_END , K_END ,
"GUIEditCursorEnd", eKeyPrio);
89 delete pKeyCursorBack;
91 delete pKeyCursorLeft;
92 delete pKeyCursorRight;
93 delete pKeyCursorHome;
106 KeyList.emplace_back(key);
131 Text =
new char[256];
141 void Edit::Deselect()
154 memmove(
Text + iSelBegin,
Text + iSelEnd, strlen(
Text + iSelEnd)+1);
168 int32_t iTextLen =
SLen(szText);
171 if (!fBufferOK) iTextLen -= iTextEnd+iTextLen - (
iMaxTextLength-1);
172 if (iTextLen <= 0)
return false;
174 EnsureBufferSize(iTextEnd + iTextLen + 1);
179 for (i=iTextLen; i; --i)
Text[
iCursorPos + i - 1] = szText[i - 1];
186 ScrollCursorInView();
192 int32_t Edit::GetCharPos(int32_t iControlXPos)
203 return Clamp<int32_t>((iControlXPos + w/2) / std::max<int32_t>(1, w), 0,
SLen(
Text));
206 for (int32_t iLastW = 0, w,h;
Text[i]; ++i)
209 if (IsUtf8StartByte(
Text[oldi]))
210 while (IsUtf8ContinuationByte(
Text[++i + 1])) ;
212 if (w - (w-iLastW)/2 >= iControlXPos)
return oldi;
218 void Edit::EnsureBufferSize(int32_t iMinBufferSize)
224 iMinBufferSize = ((iMinBufferSize - 1) & ~0xff) + 0x100;
226 char *pNewBuffer =
new char[iMinBufferSize];
234 void Edit::ScrollCursorInView()
262 bool Edit::DoFinishInput(
bool fPasting,
bool fPastingMore)
274 if (pDlg) pDlg->UserClose(
true);
293 if (iSelBegin == iSelEnd)
return false;
295 std::string buf(
Text+iSelBegin, iSelEnd-iSelBegin);
305 if (!Copy())
return false;
314 bool fSuccess =
false;
318 char * szText =
text.getMData();
321 fSuccess = !!*szText;
323 int32_t iLBPos=0, iLBPos2;
330 if (iLBPos<0 && iLBPos2<0)
break;
331 if (iLBPos2>=0 && (iLBPos2<iLBPos || iLBPos<0)) iLBPos = iLBPos2;
332 if (!iLBPos) { ++szText;
continue; }
334 if (!
InsertText(szText,
true)) fSuccess=
false;
337 if (!DoFinishInput(
true, !!*szText))
344 if (*szText) fSuccess = fSuccess &&
InsertText(szText,
true);
355 return !Inside<char>(c,
'A',
'Z')
356 && !Inside<char>(c,
'a',
'z')
357 && !Inside<char>(c,
'0',
'9')
361 bool Edit::KeyEnter()
363 DoFinishInput(
false,
false);
368 bool Edit::KeyCursorOp(
const C4KeyCodeEx &key,
const CursorOperation &op)
376 if (op == COP_BACK || op == COP_DELETE) {
DeleteSelection();
return true; }
378 if (!fShift) Deselect();
381 int32_t iMoveDir = 0, iMoveLength = 0;
382 if (op == COP_LEFT &&
iCursorPos) iMoveDir = -1;
384 else if (op == COP_BACK &&
iCursorPos && !fShift) iMoveDir = -1;
385 else if (op == COP_DELETE && (uint32_t)
iCursorPos <
SLen(
Text) && !fShift) iMoveDir = +1;
386 else if (op == COP_HOME) iMoveLength = -
iCursorPos;
388 if (iMoveDir || iMoveLength)
397 bool fNoneSpaceFound =
false, fSpaceFound =
false;;
402 if (fNoneSpaceFound && iMoveDir<0)
break;
405 iMoveLength += iMoveDir;
410 if (fSpaceFound && iMoveDir > 0)
break;
412 fNoneSpaceFound =
true;
413 iMoveLength += iMoveDir;
419 iMoveLength = iMoveDir;
420 while (IsUtf8ContinuationByte(
Text[
iCursorPos + iMoveLength])) iMoveLength +=
Sign(iMoveLength);
424 if (op == COP_BACK || op == COP_DELETE)
427 if (op == COP_DELETE) {
iCursorPos += iMoveLength; iMoveLength = -iMoveLength; }
429 char *c;
for (c =
Text+
iCursorPos; *c; ++c) *(c+iMoveLength) = *c;
431 *(c+iMoveLength) = 0;
448 ScrollCursorInView();
456 if (((
unsigned char)(c[0]))<
' ' || c[0]==0x7f)
return false;
458 if (c[0]==
'|')
return false;
502 int32_t iCharPos = GetCharPos(iX);
506 if (!iCharPos)
break;
532 if (iPrevCursorPos !=
iCursorPos) ScrollCursorInView();
541 if (iPrevCursorPos !=
iCursorPos) ScrollCursorInView();
577 int cx0,cy0,cx1,cy1;
bool fClip, fOwnClip;
614 int32_t iSelX1, iSelX2, h;
615 char c = pDrawText[iSelBegin]; pDrawText[iSelBegin]=0;
pFont->
GetTextExtent(pDrawText, iSelX1, h,
false); pDrawText[iSelBegin]=c;
616 c = pDrawText[iSelEnd]; pDrawText[iSelEnd]=0;
pFont->
GetTextExtent(pDrawText, iSelX2, h,
false); pDrawText[iSelEnd]=c;
653 if (!
Text)
return nullptr;
659 bool fAnythingSelected = (iSelBegin != iSelEnd);
660 if (fAnythingSelected)
668 if (fAnythingSelected)
684 return !!*szTargetBuf;
707 else pPrevFocusCtrl=
nullptr;
710 keys.emplace_back(K_ESCAPE);
762 void RenameEdit::FinishRename()
768 if (pDlg && pPrevFocusCtrl) pDlg->
SetFocus(pPrevFocusCtrl,
false);
790 int32_t iLabelWdt=100, iLabelHgt=24;
809 if (szPrefText) pEdit->
InsertText(szPrefText,
false);
815 int32_t iLabelWdt=100, iLabelHgt=24;
816 pUseFont->
GetTextExtent(szForText, iLabelWdt, iLabelHgt,
true);
821 if (piWdt) *piWdt = std::max<int32_t>(iLabelWdt, iEditWdt);
822 if (piHgt) *piHgt = iLabelHgt + iEditHgt + 2;
827 if (piWdt) *piWdt = iLabelWdt + iEditWdt;
828 if (piHgt) *piHgt = std::max<int32_t>(iLabelHgt, iEditHgt);
C4Application Application
C4GraphicsResource GraphicsResource
#define C4GUI_MinWoodBarHgt
#define C4GUI_EditFontColor
#define C4GUI_EditBGColor
const char * LoadResStr(const char *id)
const int32_t C4MC_Button_MiddleDown
const int32_t C4MC_Button_LeftUp
const int32_t C4MC_Button_LeftDown
const int32_t C4MC_Button_LeftDouble
int SCharPos(char cTarget, const char *szInStr, int iIndex)
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
bool IsValidUtf8(const char *text, int length)
size_t SLen(const char *sptr)
bool IsClipboardFull(bool fClipboard=true)
bool Copy(const std::string &text, bool fClipboard=true)
std::string Paste(bool fClipboard=true)
int32_t GamepadGuiControl
C4ConfigControls Controls
std::vector< C4KeyCodeEx > CodeList
void DrawFrameDw(C4Surface *sfcDest, int x1, int y1, int x2, int y2, DWORD dwClr, float width=1.0f)
void DrawBoxDw(C4Surface *sfcDest, int iX1, int iY1, int iX2, int iY2, DWORD dwClr)
bool GetPrimaryClipper(int &rX1, int &rY1, int &rX2, int &rY2)
bool SetPrimaryClipper(int iX1, int iY1, int iX2, int iY2)
void ApplyZoom(float &X, float &Y)
bool TextOut(const char *szText, CStdFont &rFont, float fZoom, C4Surface *sfcDest, float iTx, float iTy, DWORD dwFCol=0xffffffff, BYTE byForm=ALeft, bool fDoMarkup=true)
bool GetFromLeft(int32_t iWdt, int32_t iHgt, C4Rect &rcOut)
void ExpandLeft(int32_t iByWdt)
void ExpandTop(int32_t iByHgt)
bool GetFromTop(int32_t iHgt, int32_t iWdt, C4Rect &rcOut)
void GetAll(C4Rect &rcOut)
void AddElement(Element *pChild)
virtual void OnLooseFocus()
virtual void OnGetFocus(bool fByMouse)
void MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) override
void SetFocus(Control *pCtrl, bool fByMouse)
bool GetCurrentWord(char *szTargetBuf, int32_t iMaxTargetBufLen)
static int32_t GetCustomEditHeight(CStdFont *pUseFont)
ContextMenu * OnContext(C4GUI::Element *pListItem, int32_t iX, int32_t iY)
virtual InputResult OnFinishInput(bool fPasting, bool fPastingMore)
bool CharIn(const char *c) override
static int32_t GetDefaultEditHeight()
void OnCtxSelAll(C4GUI::Element *pThis)
void DoDragging(CMouse &rMouse, int32_t iX, int32_t iY, DWORD dwKeyParam) override
void DrawElement(C4TargetFacet &cgo) override
void OnCtxCopy(C4GUI::Element *pThis)
void OnCtxClear(C4GUI::Element *pThis)
Edit(const C4Rect &rtBounds, bool fFocusEdit=false)
void SetFont(CStdFont *pToFont)
C4TimeMilliseconds tLastInputTime
void OnCtxCut(C4GUI::Element *pThis)
void MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) override
void OnCtxPaste(C4GUI::Element *pThis)
bool InsertText(const char *szText, bool fUser)
void OnLooseFocus() override
void OnGetFocus(bool fByMouse) override
virtual void SetVisibility(bool fToValue)
void SetBounds(const C4Rect &rcNewBound)
virtual class Dialog * GetDlg()
void SetContextHandler(ContextHandler *pNewHd)
void Draw3DFrame(C4TargetFacet &cgo, bool fUp=false, int32_t iIndent=1, BYTE byAlpha=C4GUI_BorderAlpha, bool fDrawTop=true, int32_t iTopOff=0, bool fDrawLeft=true, int32_t iLeftOff=0)
LabeledEdit(const C4Rect &rcBounds, const char *szName, bool fMultiline, const char *szPrefText=nullptr, CStdFont *pUseFont=nullptr, uint32_t dwTextClr=C4GUI_CaptionFontClr)
static bool GetControlSize(int *piWdt, int *piHgt, const char *szForText, CStdFont *pForFont, bool fMultiline)
virtual void OnCancelRename()
virtual RenameResult OnOKRename(const char *szNewName)=0
InputResult OnFinishInput(bool fPasting, bool fPastingMore) override
void OnLooseFocus() override
RenameEdit(Label *pLabel)
void UpdateOwnPos() override
C4Rect & GetClientRect() override
static C4TimeMilliseconds Now()
int GetLineHeight() const
bool GetTextExtent(const char *szText, int32_t &rsx, int32_t &rsy, bool fCheckMarkup=true)
void AppendChars(char cChar, size_t iCnt)
const char * getData() const
bool IsWholeWordSpacer(unsigned char c)