优化textBox控件多行手动换行时,调整显示区域的问题

This commit is contained in:
睿 安
2026-01-29 09:58:13 +08:00
parent 0811c0eabb
commit bcb56200c1
13 changed files with 19 additions and 16 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,4 +1,4 @@
#include "TextBox.h" #include "TextBox.h"
#undef min #undef min
#undef max #undef max
namespace ezui { namespace ezui {
@@ -374,7 +374,7 @@ namespace ezui {
int innerW = std::max(0, Width() - (m_padLeft + m_padRight)); int innerW = std::max(0, Width() - (m_padLeft + m_padRight));
int innerH = std::max(0, Height() - (m_padTop + m_padBottom)); int innerH = std::max(0, Height() - (m_padTop + m_padBottom));
if (!m_autoWrap && !m_allowManualLineBreak) {//单行编辑框(两者都不允许) if (!m_autoWrap) {//不自动换行时需要水平拖动滚动编辑框(两者都不允许)
m_font->Get()->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP); m_font->Get()->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
bool bAlignLeft = (int(this->TextAlign) & int(HAlign::Left)); bool bAlignLeft = (int(this->TextAlign) & int(HAlign::Left));
float width = bAlignLeft ? EZUI_FLOAT_MAX : (float)innerW; float width = bAlignLeft ? EZUI_FLOAT_MAX : (float)innerW;
@@ -436,19 +436,22 @@ namespace ezui {
m_careRect.Height = m_textLayout->GetFontHeight(); m_careRect.Height = m_textLayout->GetFontHeight();
m_careRect.Width = 1 * this->GetScale(); m_careRect.Width = 1 * this->GetScale();
if (!m_autoWrap && !m_allowManualLineBreak) { // 处理水平滚动(当不自动换行时需要水平滚动)
// 使光标保持在可视内区(考虑 padding if (!m_autoWrap) {
int innerW = std::max(0, Width() - (m_padLeft + m_padRight)); // 使光标保持在可视内区(考虑 padding
int caretDrawX = m_careRect.X + m_scrollX; // 布局坐标 + 滚动 int innerW = std::max(0, Width() - (m_padLeft + m_padRight));
if (caretDrawX < 0) { // 左越界 int caretDrawX = m_careRect.X + m_scrollX; // 布局坐标 + 滚动
m_scrollX -= caretDrawX; if (caretDrawX < 0) { // 左越界
} m_scrollX -= caretDrawX;
if (caretDrawX > innerW) { // 右越界
int offsetX = innerW - caretDrawX;
m_scrollX += offsetX;
}
} }
else { // 多行:处理垂直滚动保持光标可见 if (caretDrawX > innerW) { // 右越界
int offsetX = innerW - caretDrawX;
m_scrollX += offsetX;
}
}
// 处理垂直滚动(多行模式需要垂直滚动)
if (m_autoWrap || m_allowManualLineBreak) {
int innerH = std::max(0, Height() - (m_padTop + m_padBottom)); int innerH = std::max(0, Height() - (m_padTop + m_padBottom));
int caretDrawY = m_careRect.Y + m_scrollY; // 仅布局+滚动 int caretDrawY = m_careRect.Y + m_scrollY; // 仅布局+滚动
if (caretDrawY < 0) { if (caretDrawY < 0) {
@@ -492,7 +495,7 @@ namespace ezui {
void TextBox::OnMouseWheel(const MouseEventArgs& arg) void TextBox::OnMouseWheel(const MouseEventArgs& arg)
{ {
__super::OnMouseWheel(arg); __super::OnMouseWheel(arg);
if (!m_autoWrap && !m_allowManualLineBreak) {//单行 if (!m_autoWrap) {//不自动换行时需要水平拖动滚动
int innerW = std::max(0, Width() - (m_padLeft + m_padRight)); int innerW = std::max(0, Width() - (m_padLeft + m_padRight));
int textWidth = m_fontBox.Width; int textWidth = m_fontBox.Width;
if (arg.ZDelta > 0 && textWidth > innerW) { if (arg.ZDelta > 0 && textWidth > innerW) {
@@ -560,7 +563,7 @@ namespace ezui {
BuildSelectedRect(); BuildSelectedRect();
if (!m_autoWrap && !m_allowManualLineBreak) {//单行 if (!m_autoWrap) {//不自动换行时需要水平拖动滚动
// 计算去掉左 padding 的鼠标相对文本区域坐标 // 计算去掉左 padding 的鼠标相对文本区域坐标
int innerW = std::max(0, Width() - (m_padLeft + m_padRight)); int innerW = std::max(0, Width() - (m_padLeft + m_padRight));
int textWidth = m_fontBox.Width; int textWidth = m_fontBox.Width;