📄 wg_editbox.cpp
字号:
// wg_editbox.cpp//// CEditBox class implementation////// Copyright (c) 2002 Rob Wiskow// rob-dev@boxedchaos.com//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA//#include "wgui_include_config.h"#include "wg_editbox.h"#include "wg_message_server.h"#include "wg_application.h"#include "wg_error.h"#include "wg_debug.h"#include <string>namespace wGui{CEditBox::CEditBox(const CRect& WindowRect, CWindow* pParent, CFontEngine* pFontEngine) : CWindow(WindowRect, pParent), m_SelStart(0), m_SelLength(0), m_DragStart(0), m_ScrollOffset(0), m_bReadOnly(false), m_bMouseDown(false), m_bUseMask(false), m_bLastMouseMoveInside(false){ m_sClassName = "CEditBox"; m_BGColor = COLOR_WHITE; m_ClientRect.Grow(-4); if (pFontEngine) { m_pFontEngine = pFontEngine; } else { m_pFontEngine = CApplication::Instance()->GetDefaultFontEngine(); } std::auto_ptr<CRenderedString> pRenderedString(new CRenderedString( m_pFontEngine, "", CRenderedString::VALIGN_NORMAL, CRenderedString::HALIGN_LEFT)); m_pRenderedString = pRenderedString; CMessageServer::Instance().RegisterMessageClient(this, CMessage::KEYBOARD_KEYDOWN); CMessageServer::Instance().RegisterMessageClient(this, CMessage::MOUSE_BUTTONUP); CMessageServer::Instance().RegisterMessageClient(this, CMessage::MOUSE_MOVE);}void CEditBox::SetReadOnly(bool bReadOnly){ m_BGColor = bReadOnly ? COLOR_LIGHTGRAY : COLOR_WHITE; m_bReadOnly = bReadOnly; StartDrawProc();}std::string CEditBox::GetSelText(void) const{ if (m_bUseMask) { return ""; } if (m_SelLength != 0) { unsigned int SelStartNorm=0, SelLenNorm=0; if (m_SelLength < 0) { SelStartNorm = m_SelLength + m_SelStart; SelLenNorm = abs(m_SelLength); } else { SelStartNorm = m_SelStart; SelLenNorm = m_SelLength; } return m_sWindowText.substr(SelStartNorm, SelLenNorm); } else { return ""; }}void CEditBox::Draw(void) const{ CWindow::Draw(); CPainter Painter(m_pSDLSurface); CRect SubRect(m_WindowRect); CRect DrawRect(m_WindowRect); DrawRect.Grow(-3); SubRect.Grow(-3); Painter.DrawRect(m_WindowRect, false, COLOR_BLACK); CPoint FontCenterPoint = m_WindowRect.Center(); if (m_bUseMask) { m_pRenderedString->SetMaskChar('*'); } else { m_pRenderedString->SetMaskChar(' '); } CRGBColor FontColor = m_bReadOnly ? DEFAULT_DISABLED_LINE_COLOR : DEFAULT_LINE_COLOR; if (CApplication::Instance()->GetKeyFocus() == dynamic_cast<const CWindow*>(this) && !m_bReadOnly) { CPoint Offset; std::vector<CRect> CharRects; m_pRenderedString->GetMetrics(0, &Offset, &CharRects); unsigned int SelStartNorm = 0; unsigned int SelLenNorm = abs(m_SelLength); if (m_SelLength < 0) { SelStartNorm = m_SelStart + m_SelLength; } else { SelStartNorm = m_SelStart; } // Handle scrolling // Patch for "Scrolling while selecting to left in editbox" by Oldrich Dlouhy if (! m_bMouseDown) { int RightBorder = CharRects[SelStartNorm + SelLenNorm - 1].Right() + Offset.XPos() + SubRect.Left() + m_ScrollOffset; int LeftBorder = CharRects[SelStartNorm].Left() + Offset.XPos() + m_ScrollOffset; if (m_SelLength < 0) { if (LeftBorder <= 0) { m_ScrollOffset = -(CharRects[SelStartNorm].Left() + Offset.XPos()); } else if (RightBorder > SubRect.Right()) { m_ScrollOffset = SubRect.Right() - (CharRects[SelStartNorm + SelLenNorm].Right() + Offset.XPos() + SubRect.Left()); } } else { if (RightBorder >= SubRect.Right()) { m_ScrollOffset = SubRect.Right() - (CharRects[SelStartNorm + SelLenNorm].Right() + Offset.XPos() + SubRect.Left()); } else if (LeftBorder < 0) { m_ScrollOffset = -(CharRects[SelStartNorm].Left() + Offset.XPos()); } } if (m_ScrollOffset != 0 && (CharRects[m_sWindowText.length()].Right() + Offset.XPos() + SubRect.Left() + m_ScrollOffset < SubRect.Right())) { m_ScrollOffset = SubRect.Right() - (CharRects[m_sWindowText.length()].Right() + Offset.XPos() + SubRect.Left()); if (m_ScrollOffset > 0) { m_ScrollOffset = 0; } } } // Selection if (m_SelLength != 0) { CRect SelRect; SelRect.SetBottom(SubRect.Bottom()); SelRect.SetTop(SubRect.Top()); SelRect.SetLeft(CharRects[SelStartNorm].Left() + Offset.XPos() + SubRect.Left() + m_ScrollOffset); SelRect.SetRight(CharRects[SelLenNorm + SelStartNorm - 1].Right() + Offset.XPos() + SubRect.Left() + m_ScrollOffset); SelRect.ClipTo(SubRect); Painter.DrawRect(SelRect, true, CRGBColor(102, 128, 151), CRGBColor(102, 128, 151)); } //TODO: //We should do this regardless of wether there's text selected or not. // This means we'll have to calculate the CursorPos all the time. Including when we're selecting. else { //RenderStringWithCursor int CursorPos; CursorPos = CharRects[m_SelStart].Left() + Offset.XPos() + SubRect.Left() + m_ScrollOffset; if (CursorPos >= SubRect.Left() && CursorPos <= SubRect.Right()) { Painter.DrawVLine(SubRect.Top(), SubRect.Bottom(), CursorPos, COLOR_BLACK); } } } DrawRect.SetLeft(DrawRect.Left() + m_ScrollOffset); int HeightDiff=m_pRenderedString->GetMaxFontHeight()/4; DrawRect.SetTop(DrawRect.Top() - HeightDiff); DrawRect.SetBottom(DrawRect.Bottom() - HeightDiff); m_pRenderedString->Draw(m_pSDLSurface, SubRect, DrawRect.BottomLeft(), FontColor);}void CEditBox::SetWindowText(const std::string& sText){ m_SelStart = 0; m_SelLength = 0; CWindow::SetWindowText(sText); std::auto_ptr<CRenderedString> pRenderedString(new CRenderedString( m_pFontEngine, sText, CRenderedString::VALIGN_NORMAL, CRenderedString::HALIGN_LEFT)); m_pRenderedString = pRenderedString; StartDrawProc();}bool CEditBox::OnMouseButtonDown(CPoint Point, unsigned int Button){ bool bResult = false; if (! CWindow::OnMouseButtonDown(Point, Button) && m_bVisible && (m_WindowRect.HitTest(Point) == CRect::RELPOS_INSIDE) && (Button == CMouseMessage::LEFT) && !m_bReadOnly) { if (CApplication::Instance()->GetKeyFocus() != this) { CApplication::Instance()->SetKeyFocus(this); } CPoint Offset; std::vector<CRect> CharRects; m_pRenderedString->GetMetrics(0, &Offset, &CharRects); CRect SubRect(m_WindowRect); SubRect.Grow(-3); int xDelta = abs(Point.XPos() - (CharRects[0].Left() + Offset.XPos() + SubRect.Left())); m_SelStart = 0; for (unsigned int i = 0; i < m_pRenderedString->GetLength(); ++i) { if (abs(Point.XPos() - (CharRects[i].Right() + Offset.XPos() + SubRect.Left() + m_ScrollOffset)) < xDelta) { xDelta = abs(Point.XPos() - (CharRects[i].Right() + Offset.XPos() + SubRect.Left() + m_ScrollOffset)); m_SelStart = i + 1; } } m_DragStart = m_SelStart; m_SelLength = 0; m_bMouseDown = true; StartDrawProc(); bResult = true; } return bResult;}bool CEditBox::HandleMessage(CMessage* pMessage){ bool bHandled = false; CRect SubRect(m_WindowRect); SubRect.Grow(-3); if (pMessage) { switch(pMessage->MessageType()) { case CMessage::MOUSE_BUTTONUP: m_bMouseDown = false; break; case CMessage::MOUSE_MOVE: { CMouseMessage* pMouseMessage = dynamic_cast<CMouseMessage*>(pMessage); if (pMouseMessage && m_bVisible && !m_bReadOnly)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -