From 2400d2a36f76f5d8d7b10a4ddce450387eb06d35 Mon Sep 17 00:00:00 2001 From: Mind Rapist Date: Wed, 18 Feb 2026 01:00:24 +0200 Subject: [PATCH] Various fixes and improvements --- src/EterLib/GrpTextInstance.cpp | 64 ++++++++++++++++--- src/EterLib/GrpTextInstance.h | 8 +++ src/EterPythonLib/PythonWindow.cpp | 12 ++++ src/EterPythonLib/PythonWindow.h | 5 ++ .../PythonWindowManagerModule.cpp | 38 +++++++++++ 5 files changed, 119 insertions(+), 8 deletions(-) diff --git a/src/EterLib/GrpTextInstance.cpp b/src/EterLib/GrpTextInstance.cpp index 3cc4072..c987b53 100644 --- a/src/EterLib/GrpTextInstance.cpp +++ b/src/EterLib/GrpTextInstance.cpp @@ -793,10 +793,22 @@ void CGraphicTextInstance::Render(RECT * pClipRect) } // --- Selection background (Ctrl+A / shift-select) --- - if (m_isCursor && CIME::ms_bCaptureInput) + // MR-15: Expose text selection highlighting to Python { - int selBegin = CIME::GetSelBegin(); - int selEnd = CIME::GetSelEnd(); + // Determine selection range: IME state for active input fields, local state otherwise + int selBegin, selEnd; + + if (m_isCursor && CIME::ms_bCaptureInput) + { + selBegin = CIME::GetSelBegin(); + selEnd = CIME::GetSelEnd(); + } + else + { + selBegin = m_selStart; + selEnd = m_selEnd; + } + // MR-15: -- END OF -- Expose text selection highlighting to Python if (selBegin > selEnd) std::swap(selBegin, selEnd); @@ -818,18 +830,39 @@ void CGraphicTextInstance::Render(RECT * pClipRect) __GetTextPos(visualSelBegin, &sx, &sy); __GetTextPos(visualSelEnd, &ex, &sy); - // Handle RTL - use the computed direction for this text instance + // MR-15: Expose text highlighting to Python + // Apply horizontal alignment (must match text rendering offset) + float alignOffset = 0.0f; + if (m_computedRTL) { - sx += m_v3Position.x - m_textWidth; - ex += m_v3Position.x - m_textWidth; + switch (m_hAlign) + { + case HORIZONTAL_ALIGN_LEFT: + alignOffset = -(float)m_textWidth; + break; + case HORIZONTAL_ALIGN_CENTER: + alignOffset = -float(m_textWidth / 2); + break; + } } else { - sx += m_v3Position.x; - ex += m_v3Position.x; + switch (m_hAlign) + { + case HORIZONTAL_ALIGN_RIGHT: + alignOffset = -(float)m_textWidth; + break; + case HORIZONTAL_ALIGN_CENTER: + alignOffset = -float(m_textWidth / 2); + break; + } } + sx += m_v3Position.x + alignOffset; + ex += m_v3Position.x + alignOffset; + // MR-15: -- END OF -- Expose text highlighting to Python + // Apply vertical alignment float top = m_v3Position.y; float bot = m_v3Position.y + m_textHeight; @@ -1076,6 +1109,18 @@ void CGraphicTextInstance::HideCursor() m_isCursor = false; } +void CGraphicTextInstance::SetSelection(int iStart, int iEnd) +{ + m_selStart = iStart; + m_selEnd = iEnd; +} + +void CGraphicTextInstance::ClearSelection() +{ + m_selStart = 0; + m_selEnd = 0; +} + void CGraphicTextInstance::ShowOutLine() { m_isOutline = true; @@ -1317,6 +1362,9 @@ void CGraphicTextInstance::__Initialize() m_isSecret = false; m_isMultiLine = false; + m_selStart = 0; + m_selEnd = 0; + m_isOutline = false; m_fFontFeather = c_fFontFeather; diff --git a/src/EterLib/GrpTextInstance.h b/src/EterLib/GrpTextInstance.h index 4bb03f9..e82caf7 100644 --- a/src/EterLib/GrpTextInstance.h +++ b/src/EterLib/GrpTextInstance.h @@ -47,6 +47,11 @@ class CGraphicTextInstance void ShowCursor(); void HideCursor(); + // MR-15: Expose text highlighting to Python + void SetSelection(int iStart, int iEnd); + void ClearSelection(); + // MR-15: -- END OF -- Expose text highlighting to Python + void ShowOutLine(); void HideOutLine(); @@ -120,6 +125,9 @@ class CGraphicTextInstance bool m_isSecret; bool m_isMultiLine; + int m_selStart; + int m_selEnd; + bool m_isOutline; float m_fFontFeather; diff --git a/src/EterPythonLib/PythonWindow.cpp b/src/EterPythonLib/PythonWindow.cpp index f98e875..ea46775 100644 --- a/src/EterPythonLib/PythonWindow.cpp +++ b/src/EterPythonLib/PythonWindow.cpp @@ -1126,6 +1126,18 @@ namespace UI return m_TextInstance.PixelPositionToCharacterPosition(lx); } + // MR-15: Expose text highlighting to Python + void CTextLine::SetSelection(int iStart, int iEnd) + { + m_TextInstance.SetSelection(iStart, iEnd); + } + + void CTextLine::ClearSelection() + { + m_TextInstance.ClearSelection(); + } + // MR-15: -- END OF -- Expose text highlighting to Python + void CTextLine::SetBaseDirection(int iDir) { if (iDir == 2) diff --git a/src/EterPythonLib/PythonWindow.h b/src/EterPythonLib/PythonWindow.h index 93cb66d..0a54559 100644 --- a/src/EterPythonLib/PythonWindow.h +++ b/src/EterPythonLib/PythonWindow.h @@ -292,6 +292,11 @@ namespace UI void HideCursor(); int GetCursorPosition(); + // MR-15: Expose text highlighting to Python + void SetSelection(int iStart, int iEnd); + void ClearSelection(); + // MR-15: -- END OF -- Expose text highlighting to Python + void SetText(const char * c_szText); const char * GetText(); diff --git a/src/EterPythonLib/PythonWindowManagerModule.cpp b/src/EterPythonLib/PythonWindowManagerModule.cpp index dfdcdc9..15b6dd2 100644 --- a/src/EterPythonLib/PythonWindowManagerModule.cpp +++ b/src/EterPythonLib/PythonWindowManagerModule.cpp @@ -1899,6 +1899,40 @@ PyObject * wndTextGetCursorPosition(PyObject * poSelf, PyObject * poArgs) return Py_BuildValue("i", ((UI::CTextLine*)pWindow)->GetCursorPosition()); } +PyObject * wndTextSetSelection(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + int iStart; + + if (!PyTuple_GetInteger(poArgs, 1, &iStart)) + return Py_BuildException(); + + int iEnd; + + if (!PyTuple_GetInteger(poArgs, 2, &iEnd)) + return Py_BuildException(); + + ((UI::CTextLine*)pWindow)->SetSelection(iStart, iEnd); + + return Py_BuildNone(); +} + +PyObject * wndTextClearSelection(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + ((UI::CTextLine*)pWindow)->ClearSelection(); + + return Py_BuildNone(); +} + PyObject * wndNumberSetNumber(PyObject * poSelf, PyObject * poArgs) { UI::CWindow * pWindow; @@ -2567,6 +2601,10 @@ void initwndMgr() { "GetTextSize", wndTextGetTextSize, METH_VARARGS }, { "ShowCursor", wndTextShowCursor, METH_VARARGS }, { "HideCursor", wndTextHideCursor, METH_VARARGS }, + // MR-15: Expose text highlighting to Python + { "SetSelection", wndTextSetSelection, METH_VARARGS }, + { "ClearSelection", wndTextClearSelection, METH_VARARGS }, + // MR-15: -- END OF -- Expose text highlighting to Python { "GetCursorPosition", wndTextGetCursorPosition, METH_VARARGS }, // NumberLine { "SetNumber", wndNumberSetNumber, METH_VARARGS },