This commit is contained in:
zhongyang219
2026-02-01 14:10:39 +08:00
parent 9ff5b0fdd8
commit bfcd952803
4 changed files with 177 additions and 206 deletions
+161 -6
View File
@@ -1,20 +1,175 @@
#include "stdafx.h"
#include "EditControl.h"
void UiElement::EditControl::Create(CWnd* parent)
{
m_edit_ctrl = std::make_unique<CEdit>();
m_edit_ctrl->Create(WS_CHILDWINDOW | WS_BORDER | WS_VISIBLE | WS_CLIPCHILDREN | ES_AUTOHSCROLL, GetRect(), parent, system_ctrl_id);
system_ctrl_id++;
m_edit_ctrl->SetFont(parent->GetFont());
m_edit_ctrl->ShowWindow(SW_SHOW);
}
void UiElement::EditControl::Draw()
{
CalculateRect();
if (m_edit_ctrl != nullptr && IsWindow(m_edit_ctrl->m_hWnd))
//DrawTextCtrl();
if (IsEditControlValid())
{
m_edit_ctrl->SetWindowPos(nullptr, GetRect().left, GetRect().top, GetRect().Width(), GetRect().Height(), SWP_NOZORDER);
}
}
void UiElement::EditControl::Create(CWnd* parent)
void UiElement::EditControl::DrawTextCtrl()
{
m_edit_ctrl = std::make_unique<CEdit>();
m_edit_ctrl->Create(WS_CHILD | WS_VISIBLE | WS_BORDER, GetRect(), parent, system_ctrl_id);
system_ctrl_id++;
m_edit_ctrl->SetFont(parent->GetFont());
//绘制背景
COLORREF back_color;
if (hover)
back_color = ui->GetUIColors().color_button_hover;
else
back_color = ui->GetUIColors().color_control_bar_back;
ui->DrawRectangle(rect, back_color);
//计算文本区域位置
CRect rect_text{ rect };
rect_text.left += ui->DPI(4);
rect_text.right -= ui->DPI(4);
//获取当前文本
CString text;
if (IsEditControlValid())
m_edit_ctrl->GetWindowText(text);
//绘制光标
if (is_edit && m_edit_ctrl != nullptr)
{
int text_height = ui->DPI(16);
int start_char = 0;
int end_char = 0;
m_edit_ctrl->GetSel(start_char, end_char);
int text_length = text.GetLength();
int start_width = GetTextWidthByPos(start_char, text);
int end_width = GetTextWidthByPos(end_char, text);
//绘制选择区域
if (start_char < end_char)
{
CRect rect_sel = rect;
rect_sel.top = rect.top + (rect.Height() - text_height) / 2;
rect_sel.bottom = rect_sel.top + text_height;
rect_sel.left = rect_text.left + start_width;
rect_sel.right = rect_text.left + end_width;
rect_sel &= rect_text;
COLORREF color_selection;
if (theApp.m_app_setting_data.dark_mode)
color_selection = theApp.m_app_setting_data.theme_color.dark1;
else
color_selection = theApp.m_app_setting_data.theme_color.light1_5;
ui->GetDrawer().FillRect(rect_sel, color_selection);
}
CPoint point1;
point1.x = rect_text.left + end_width;
point1.y = rect.top + (rect.Height() - text_height) / 2;
if (rect.PtInRect(point1))
{
CPoint point2 = point1;
point2.y += text_height;
ui->GetDrawer().DrawLine(point1, point2, ui->GetUIColors().color_text, ui->DPI(1), false);
}
}
//绘制文本
COLORREF text_color = ui->GetUIColors().color_text;
out_of_bounds = false;
ui->GetDrawer().DrawWindowText(rect_text, text.GetString(), text_color, Alignment::LEFT, true, false, false, &out_of_bounds);
}
bool UiElement::EditControl::LButtonUp(CPoint point)
{
if (rect.PtInRect(point))
{
//点击时显示关联的控件
if (rect.PtInRect(point))
{
if (IsEditControlValid())
{
m_edit_ctrl->SetWindowPos(nullptr, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER);
is_edit = true;
//m_edit_ctrl->ShowWindow(SW_SHOW);
}
}
return true;
}
else
{
if (IsEditControlValid())
{
is_edit = false;
//m_edit_ctrl->ShowWindow(SW_HIDE);
}
}
return false;
}
bool UiElement::EditControl::LButtonDown(CPoint point)
{
return false;
}
bool UiElement::EditControl::MouseMove(CPoint point)
{
hover = rect.PtInRect(point);
if (out_of_bounds && IsEditControlValid())
{
if (!last_hover && hover)
{
CString tooltip_text;
m_edit_ctrl->GetWindowText(tooltip_text);
ui->UpdateMouseToolTip(TooltipIndex::TEXT_BLOCK, tooltip_text.GetString());
}
if (hover)
{
ui->UpdateMouseToolTipPosition(TooltipIndex::TEXT_BLOCK, rect);
}
last_hover = hover;
}
else
{
ui->UpdateMouseToolTipPosition(TooltipIndex::TEXT_BLOCK, CRect());
}
return false;
}
bool UiElement::EditControl::MouseLeave()
{
hover = false;
return false;
}
bool UiElement::EditControl::SetCursor()
{
if (hover && IsEditControlValid())
{
::SetCursor(::LoadCursor(NULL, IDC_IBEAM));
return true;
}
return false;
}
bool UiElement::EditControl::IsEditControlValid()
{
return m_edit_ctrl != nullptr && IsWindow(m_edit_ctrl->m_hWnd);
}
int UiElement::EditControl::GetTextWidthByPos(int pos, const CString& text)
{
if (pos <= 0)
return 0;
if (pos >= text.GetLength())
return ui->GetDrawer().GetTextExtent(text).cx;
return ui->GetDrawer().GetTextExtent(text.Left(pos)).cx;
}
+16 -1
View File
@@ -5,11 +5,26 @@ namespace UiElement
class EditControl : public Element
{
public:
virtual void Draw() override;
void Create(CWnd* parent);
virtual void Draw() override;
virtual bool LButtonUp(CPoint point) override;
virtual bool LButtonDown(CPoint point) override;
virtual bool MouseMove(CPoint point) override;
virtual bool MouseLeave() override;
virtual bool SetCursor() override;
protected:
void DrawTextCtrl();
bool IsEditControlValid();
int GetTextWidthByPos(int pos, const CString& text);
private:
std::unique_ptr<CEdit> m_edit_ctrl;
bool hover{};
bool is_edit{};
bool out_of_bounds{};
bool last_hover{};
};
}
-163
View File
@@ -1,163 +0,0 @@
#include "stdafx.h"
#include "TextBlock.h"
void UiElement::TextBlock::Draw()
{
CalculateRect();
//绘制背景
COLORREF back_color;
if (hover)
back_color = ui->GetUIColors().color_button_hover;
else
back_color = ui->GetUIColors().color_control_bar_back;
ui->DrawRectangle(rect, back_color);
//计算文本区域位置
CRect rect_text{ rect };
rect_text.left += ui->DPI(4);
rect_text.right -= ui->DPI(4);
//绘制光标
if (is_edit && m_edit_ctrl != nullptr)
{
int text_height = ui->DPI(16);
int start_char = 0;
int end_char = 0;
m_edit_ctrl->GetSel(start_char, end_char);
int text_length = static_cast<int>(text.size());
int start_width = GetTextWidthByPos(start_char);
int end_width = GetTextWidthByPos(end_char);
//绘制选择区域
if (start_char < end_char)
{
CRect rect_sel = rect;
rect_sel.top = rect.top + (rect.Height() - text_height) / 2;
rect_sel.bottom = rect_sel.top + text_height;
rect_sel.left = rect_text.left + start_width;
rect_sel.right = rect_text.left + end_width;
rect_sel &= rect_text;
COLORREF color_selection;
if (theApp.m_app_setting_data.dark_mode)
color_selection = theApp.m_app_setting_data.theme_color.dark1;
else
color_selection = theApp.m_app_setting_data.theme_color.light1_5;
ui->GetDrawer().FillRect(rect_sel, color_selection);
}
CPoint point1;
point1.x = rect_text.left + end_width;
point1.y = rect.top + (rect.Height() - text_height) / 2;
if (rect.PtInRect(point1))
{
CPoint point2 = point1;
point2.y += text_height;
ui->GetDrawer().DrawLine(point1, point2, ui->GetUIColors().color_text, ui->DPI(1), false);
}
}
//绘制文本
COLORREF text_color = ui->GetUIColors().color_text;
out_of_bounds = false;
ui->GetDrawer().DrawWindowText(rect_text, text.c_str(), text_color, Alignment::LEFT, true, false, false, &out_of_bounds);
Element::Draw();
}
void UiElement::TextBlock::SetEditCtrl(CEdit* edit_ctrl)
{
m_edit_ctrl = edit_ctrl;
}
void UiElement::TextBlock::UpdateText()
{
if (m_edit_ctrl != nullptr)
{
CString str;
m_edit_ctrl->GetWindowText(str);
text = str.GetString();
}
}
bool UiElement::TextBlock::LButtonUp(CPoint point)
{
if (rect.PtInRect(point))
{
//点击时显示关联的控件
if (rect.PtInRect(point))
{
if (m_edit_ctrl != nullptr)
{
m_edit_ctrl->SetWindowText(text.c_str());
m_edit_ctrl->SetWindowPos(nullptr, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER);
m_edit_ctrl->ShowWindow(SW_SHOW);
is_edit = true;
}
}
return true;
}
else
{
if (m_edit_ctrl != nullptr)
{
m_edit_ctrl->ShowWindow(SW_HIDE);
is_edit = false;
}
}
return false;
}
bool UiElement::TextBlock::LButtonDown(CPoint point)
{
return false;
}
bool UiElement::TextBlock::MouseMove(CPoint point)
{
hover = rect.PtInRect(point);
if (out_of_bounds)
{
if (!last_hover && hover)
{
std::wstring tooltip_text = GetText();
ui->UpdateMouseToolTip(TooltipIndex::TEXT_BLOCK, tooltip_text.c_str());
}
if (hover)
{
ui->UpdateMouseToolTipPosition(TooltipIndex::TEXT_BLOCK, rect);
}
last_hover = hover;
}
else
{
ui->UpdateMouseToolTipPosition(TooltipIndex::TEXT_BLOCK, CRect());
}
return false;
}
bool UiElement::TextBlock::MouseLeave()
{
hover = false;
return false;
}
bool UiElement::TextBlock::SetCursor()
{
if (hover && m_edit_ctrl != nullptr)
{
::SetCursor(::LoadCursor(NULL, IDC_IBEAM));
return true;
}
return false;
}
int UiElement::TextBlock::GetTextWidthByPos(int pos)
{
if (pos <= 0)
return 0;
if (pos >= static_cast<int>(text.size()))
return ui->GetDrawer().GetTextExtent(text.c_str()).cx;
return ui->GetDrawer().GetTextExtent(text.substr(0, pos).c_str()).cx;
}
-36
View File
@@ -1,36 +0,0 @@
#pragma once
#include "UIElement/UIElement.h"
namespace UiElement
{
//文本编辑元素
//TextBlock本身无法实现文本输入功能,它需要关联一个CEdit控件,当鼠标点击会显示关联的控件,当CEdit文本改变时,需要手动调用UpdateText更新文本
class TextBlock : public Element
{
public:
void SetEditCtrl(CEdit* edit_ctrl);
void UpdateText();
const std::wstring& GetText() const { return text; }
void SetText(const std::wstring& str) { text = str; }
virtual void Draw() override;
virtual bool LButtonUp(CPoint point) override;
virtual bool LButtonDown(CPoint point) override;
virtual bool MouseMove(CPoint point) override;
virtual bool MouseLeave() override;
virtual bool SetCursor() override;
protected:
int GetTextWidthByPos(int pos);
protected:
CEdit* m_edit_ctrl{};
bool hover{};
std::wstring text;
bool show_cursor{};
bool is_edit{}; //是否处于编辑状态
bool last_hover{};
bool out_of_bounds{};
};
}