Added a wxRichTextCtrl-specific caret implementation in case of need
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@53408 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -70,6 +70,14 @@
|
|||||||
#include "wx/dataobj.h"
|
#include "wx/dataobj.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Setting wxRICHTEXT_USE_OWN_CARET to 1 implements a non-flashing
|
||||||
|
// cursor reliably without using wxClientDC in case there
|
||||||
|
// are platform-specific problems with the generic caret.
|
||||||
|
#define wxRICHTEXT_USE_OWN_CARET 0
|
||||||
|
|
||||||
|
// Switch off for binary compatibility, on for faster drawing
|
||||||
|
#define wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING 0
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Special characters
|
* Special characters
|
||||||
*/
|
*/
|
||||||
@@ -285,9 +293,6 @@ class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextBuffer;
|
|||||||
|
|
||||||
#define wxSCRIPT_MUL_FACTOR 1.5
|
#define wxSCRIPT_MUL_FACTOR 1.5
|
||||||
|
|
||||||
// Switch off for binary compatibility, on for faster drawing
|
|
||||||
#define wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING 0
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* wxRichTextRange class declaration
|
* wxRichTextRange class declaration
|
||||||
* This stores beginning and end positions for a range of data.
|
* This stores beginning and end positions for a range of data.
|
||||||
|
@@ -7073,6 +7073,9 @@ void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent
|
|||||||
m_ctrl->Refresh(false);
|
m_ctrl->Refresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxRICHTEXT_USE_OWN_CARET
|
||||||
|
m_ctrl->PositionCaret();
|
||||||
|
#endif
|
||||||
if (sendUpdateEvent)
|
if (sendUpdateEvent)
|
||||||
m_ctrl->SendTextUpdatedEvent();
|
m_ctrl->SendTextUpdatedEvent();
|
||||||
}
|
}
|
||||||
@@ -7222,6 +7225,9 @@ bool wxRichTextImage::GetRangeSize(const wxRichTextRange& range, wxSize& size, i
|
|||||||
if (!range.IsWithin(GetRange()))
|
if (!range.IsWithin(GetRange()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!m_image.Ok())
|
||||||
|
((wxRichTextImage*) this)->LoadFromBlock();
|
||||||
|
|
||||||
#if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS
|
#if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS
|
||||||
if (g_UseGlobalPartialTextExtents)
|
if (g_UseGlobalPartialTextExtents)
|
||||||
{
|
{
|
||||||
|
@@ -60,6 +60,69 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED)
|
|||||||
DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_SELECTION_CHANGED)
|
DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_SELECTION_CHANGED)
|
||||||
DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_BUFFER_RESET)
|
DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_BUFFER_RESET)
|
||||||
|
|
||||||
|
#if wxRICHTEXT_USE_OWN_CARET
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* wxRichTextCaret
|
||||||
|
*
|
||||||
|
* This implements a non-flashing cursor in case there
|
||||||
|
* are platform-specific problems with the generic caret.
|
||||||
|
* wxRICHTEXT_USE_OWN_CARET is set in richtextbuffer.h.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class wxRichTextCaret: public wxCaret
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// ctors
|
||||||
|
// -----
|
||||||
|
// default - use Create()
|
||||||
|
wxRichTextCaret() { Init(); }
|
||||||
|
// creates a block caret associated with the given window
|
||||||
|
wxRichTextCaret(wxRichTextCtrl *window, int width, int height)
|
||||||
|
: wxCaret(window, width, height) { Init(); m_richTextCtrl = window; }
|
||||||
|
wxRichTextCaret(wxRichTextCtrl *window, const wxSize& size)
|
||||||
|
: wxCaret(window, size) { Init(); m_richTextCtrl = window; }
|
||||||
|
|
||||||
|
virtual ~wxRichTextCaret();
|
||||||
|
|
||||||
|
// implementation
|
||||||
|
// --------------
|
||||||
|
|
||||||
|
// called by wxWindow (not using the event tables)
|
||||||
|
virtual void OnSetFocus();
|
||||||
|
virtual void OnKillFocus();
|
||||||
|
|
||||||
|
// draw the caret on the given DC
|
||||||
|
void DoDraw(wxDC *dc);
|
||||||
|
|
||||||
|
// get the visible count
|
||||||
|
int GetVisibleCount() const { return m_countVisible; }
|
||||||
|
|
||||||
|
// delay repositioning
|
||||||
|
bool GetNeedsUpdate() const { return m_needsUpdate; }
|
||||||
|
void SetNeedsUpdate(bool needsUpdate = true ) { m_needsUpdate = needsUpdate; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void DoShow();
|
||||||
|
virtual void DoHide();
|
||||||
|
virtual void DoMove();
|
||||||
|
virtual void DoSize();
|
||||||
|
|
||||||
|
// refresh the caret
|
||||||
|
void Refresh();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
int m_xOld,
|
||||||
|
m_yOld;
|
||||||
|
bool m_hasFocus; // true => our window has focus
|
||||||
|
bool m_needsUpdate; // must be repositioned
|
||||||
|
|
||||||
|
wxRichTextCtrl* m_richTextCtrl;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
IMPLEMENT_CLASS( wxRichTextCtrl, wxControl )
|
IMPLEMENT_CLASS( wxRichTextCtrl, wxControl )
|
||||||
|
|
||||||
IMPLEMENT_CLASS( wxRichTextEvent, wxNotifyEvent )
|
IMPLEMENT_CLASS( wxRichTextEvent, wxNotifyEvent )
|
||||||
@@ -178,8 +241,11 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va
|
|||||||
GetBuffer().Reset();
|
GetBuffer().Reset();
|
||||||
GetBuffer().SetRichTextCtrl(this);
|
GetBuffer().SetRichTextCtrl(this);
|
||||||
|
|
||||||
|
#if wxRICHTEXT_USE_OWN_CARET
|
||||||
|
SetCaret(new wxRichTextCaret(this, wxRICHTEXT_DEFAULT_CARET_WIDTH, 16));
|
||||||
|
#else
|
||||||
SetCaret(new wxCaret(this, wxRICHTEXT_DEFAULT_CARET_WIDTH, 16));
|
SetCaret(new wxCaret(this, wxRICHTEXT_DEFAULT_CARET_WIDTH, 16));
|
||||||
GetCaret()->Show();
|
#endif
|
||||||
|
|
||||||
// Tell the sizers to use the given or best size
|
// Tell the sizers to use the given or best size
|
||||||
SetInitialSize(size);
|
SetInitialSize(size);
|
||||||
@@ -273,8 +339,10 @@ void wxRichTextCtrl::Clear()
|
|||||||
/// Painting
|
/// Painting
|
||||||
void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
|
void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
if (GetCaret() && GetCaret()->IsVisible())
|
#if !wxRICHTEXT_USE_OWN_CARET
|
||||||
|
if (GetCaret() && !IsFrozen())
|
||||||
GetCaret()->Hide();
|
GetCaret()->Hide();
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
#if wxRICHTEXT_BUFFERED_PAINTING
|
#if wxRICHTEXT_BUFFERED_PAINTING
|
||||||
@@ -284,8 +352,10 @@ void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
|
|||||||
#endif
|
#endif
|
||||||
PrepareDC(dc);
|
PrepareDC(dc);
|
||||||
|
|
||||||
if (m_freezeCount > 0)
|
if (IsFrozen())
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dc.SetFont(GetFont());
|
dc.SetFont(GetFont());
|
||||||
|
|
||||||
@@ -306,12 +376,21 @@ void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
|
|||||||
}
|
}
|
||||||
|
|
||||||
GetBuffer().Draw(dc, GetBuffer().GetRange(), GetInternalSelectionRange(), drawingArea, 0 /* descent */, 0 /* flags */);
|
GetBuffer().Draw(dc, GetBuffer().GetRange(), GetInternalSelectionRange(), drawingArea, 0 /* descent */, 0 /* flags */);
|
||||||
|
|
||||||
|
#if wxRICHTEXT_USE_OWN_CARET
|
||||||
|
if (GetCaret()->IsVisible())
|
||||||
|
{
|
||||||
|
((wxRichTextCaret*) GetCaret())->DoDraw(& dc);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetCaret() && !GetCaret()->IsVisible())
|
#if !wxRICHTEXT_USE_OWN_CARET
|
||||||
|
if (GetCaret())
|
||||||
GetCaret()->Show();
|
GetCaret()->Show();
|
||||||
|
|
||||||
PositionCaret();
|
PositionCaret();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty implementation, to prevent flicker
|
// Empty implementation, to prevent flicker
|
||||||
@@ -323,22 +402,33 @@ void wxRichTextCtrl::OnSetFocus(wxFocusEvent& WXUNUSED(event))
|
|||||||
{
|
{
|
||||||
if (GetCaret())
|
if (GetCaret())
|
||||||
{
|
{
|
||||||
if (!GetCaret()->IsVisible())
|
#if !wxRICHTEXT_USE_OWN_CARET
|
||||||
GetCaret()->Show();
|
|
||||||
PositionCaret();
|
PositionCaret();
|
||||||
|
#endif
|
||||||
|
GetCaret()->Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!IsFrozen())
|
#if defined(__WXGTK__) && !wxRICHTEXT_USE_OWN_CARET
|
||||||
// Refresh(false);
|
// Work around dropouts when control is focused
|
||||||
|
if (!IsFrozen())
|
||||||
|
{
|
||||||
|
Refresh(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxRichTextCtrl::OnKillFocus(wxFocusEvent& WXUNUSED(event))
|
void wxRichTextCtrl::OnKillFocus(wxFocusEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
if (GetCaret() && GetCaret()->IsVisible())
|
if (GetCaret())
|
||||||
GetCaret()->Hide();
|
GetCaret()->Hide();
|
||||||
|
|
||||||
// if (!IsFrozen())
|
#if defined(__WXGTK__) && !wxRICHTEXT_USE_OWN_CARET
|
||||||
// Refresh(false);
|
// Work around dropouts when control is focused
|
||||||
|
if (!IsFrozen())
|
||||||
|
{
|
||||||
|
Refresh(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxRichTextCtrl::OnCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event))
|
void wxRichTextCtrl::OnCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event))
|
||||||
@@ -1128,7 +1218,9 @@ bool wxRichTextCtrl::ScrollIntoView(long position, int keyCode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !wxRICHTEXT_USE_OWN_CARET
|
||||||
if (scrolled)
|
if (scrolled)
|
||||||
|
#endif
|
||||||
PositionCaret();
|
PositionCaret();
|
||||||
|
|
||||||
return scrolled;
|
return scrolled;
|
||||||
@@ -1735,10 +1827,18 @@ void wxRichTextCtrl::OnSize(wxSizeEvent& event)
|
|||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Idle-time processing
|
/// Idle-time processing
|
||||||
void wxRichTextCtrl::OnIdle(wxIdleEvent& event)
|
void wxRichTextCtrl::OnIdle(wxIdleEvent& event)
|
||||||
{
|
{
|
||||||
|
#if wxRICHTEXT_USE_OWN_CARET
|
||||||
|
if (((wxRichTextCaret*) GetCaret())->GetNeedsUpdate())
|
||||||
|
{
|
||||||
|
((wxRichTextCaret*) GetCaret())->SetNeedsUpdate(false);
|
||||||
|
PositionCaret();
|
||||||
|
GetCaret()->Show();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const int layoutInterval = wxRICHTEXT_DEFAULT_LAYOUT_INTERVAL;
|
const int layoutInterval = wxRICHTEXT_DEFAULT_LAYOUT_INTERVAL;
|
||||||
|
|
||||||
if (m_fullLayoutRequired && (wxGetLocalTimeMillis() > (m_fullLayoutTime + layoutInterval)))
|
if (m_fullLayoutRequired && (wxGetLocalTimeMillis() > (m_fullLayoutTime + layoutInterval)))
|
||||||
@@ -1764,7 +1864,14 @@ void wxRichTextCtrl::OnIdle(wxIdleEvent& event)
|
|||||||
/// Scrolling
|
/// Scrolling
|
||||||
void wxRichTextCtrl::OnScroll(wxScrollWinEvent& event)
|
void wxRichTextCtrl::OnScroll(wxScrollWinEvent& event)
|
||||||
{
|
{
|
||||||
// Not used
|
#if wxRICHTEXT_USE_OWN_CARET
|
||||||
|
if (!((wxRichTextCaret*) GetCaret())->GetNeedsUpdate())
|
||||||
|
{
|
||||||
|
GetCaret()->Hide();
|
||||||
|
((wxRichTextCaret*) GetCaret())->SetNeedsUpdate();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2741,8 +2848,6 @@ void wxRichTextCtrl::PositionCaret()
|
|||||||
if (!GetCaret())
|
if (!GetCaret())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//wxLogDebug(wxT("PositionCaret"));
|
|
||||||
|
|
||||||
wxRect caretRect;
|
wxRect caretRect;
|
||||||
if (GetCaretPositionForIndex(GetCaretPosition(), caretRect))
|
if (GetCaretPositionForIndex(GetCaretPosition(), caretRect))
|
||||||
{
|
{
|
||||||
@@ -2751,8 +2856,12 @@ void wxRichTextCtrl::PositionCaret()
|
|||||||
wxPoint pt = GetPhysicalPoint(newPt);
|
wxPoint pt = GetPhysicalPoint(newPt);
|
||||||
if (GetCaret()->GetPosition() != pt || GetCaret()->GetSize() != newSz)
|
if (GetCaret()->GetPosition() != pt || GetCaret()->GetSize() != newSz)
|
||||||
{
|
{
|
||||||
|
//wxLogDebug(wxT("Positioning caret %d, %d"), pt.x, pt.y);
|
||||||
|
GetCaret()->Hide();
|
||||||
|
if (GetCaret()->GetSize() != newSz)
|
||||||
|
GetCaret()->SetSize(newSz);
|
||||||
GetCaret()->Move(pt);
|
GetCaret()->Move(pt);
|
||||||
GetCaret()->SetSize(newSz);
|
GetCaret()->Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3282,5 +3391,126 @@ bool wxRichTextCtrlRefreshForSelectionChange(wxRichTextCtrl& ctrl, const wxRichT
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxRICHTEXT_USE_OWN_CARET
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// initialization and destruction
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxRichTextCaret::Init()
|
||||||
|
{
|
||||||
|
m_hasFocus = true;
|
||||||
|
|
||||||
|
m_xOld =
|
||||||
|
m_yOld = -1;
|
||||||
|
m_richTextCtrl = NULL;
|
||||||
|
m_needsUpdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxRichTextCaret::~wxRichTextCaret()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// showing/hiding/moving the caret (base class interface)
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxRichTextCaret::DoShow()
|
||||||
|
{
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxRichTextCaret::DoHide()
|
||||||
|
{
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxRichTextCaret::DoMove()
|
||||||
|
{
|
||||||
|
if (IsVisible())
|
||||||
|
{
|
||||||
|
Refresh();
|
||||||
|
|
||||||
|
if (m_xOld != -1 && m_yOld != -1)
|
||||||
|
{
|
||||||
|
if (m_richTextCtrl)
|
||||||
|
{
|
||||||
|
wxRect rect(GetPosition(), GetSize());
|
||||||
|
m_richTextCtrl->RefreshRect(rect, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_xOld = m_x;
|
||||||
|
m_yOld = m_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxRichTextCaret::DoSize()
|
||||||
|
{
|
||||||
|
int countVisible = m_countVisible;
|
||||||
|
if (countVisible > 0)
|
||||||
|
{
|
||||||
|
m_countVisible = 0;
|
||||||
|
DoHide();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (countVisible > 0)
|
||||||
|
{
|
||||||
|
m_countVisible = countVisible;
|
||||||
|
DoShow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// handling the focus
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxRichTextCaret::OnSetFocus()
|
||||||
|
{
|
||||||
|
m_hasFocus = true;
|
||||||
|
|
||||||
|
if ( IsVisible() )
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxRichTextCaret::OnKillFocus()
|
||||||
|
{
|
||||||
|
m_hasFocus = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// drawing the caret
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxRichTextCaret::Refresh()
|
||||||
|
{
|
||||||
|
if (m_richTextCtrl)
|
||||||
|
{
|
||||||
|
wxRect rect(GetPosition(), GetSize());
|
||||||
|
m_richTextCtrl->RefreshRect(rect, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxRichTextCaret::DoDraw(wxDC *dc)
|
||||||
|
{
|
||||||
|
dc->SetPen( *wxBLACK_PEN );
|
||||||
|
|
||||||
|
dc->SetBrush(*(m_hasFocus ? wxBLACK_BRUSH : wxTRANSPARENT_BRUSH));
|
||||||
|
dc->SetPen(*wxBLACK_PEN);
|
||||||
|
|
||||||
|
// VZ: unfortunately, the rectangle comes out a pixel smaller when this is
|
||||||
|
// done under wxGTK - no idea why
|
||||||
|
//dc->SetLogicalFunction(wxINVERT);
|
||||||
|
|
||||||
|
wxPoint pt(m_x, m_y);
|
||||||
|
|
||||||
|
if (m_richTextCtrl)
|
||||||
|
{
|
||||||
|
pt = m_richTextCtrl->GetLogicalPoint(pt);
|
||||||
|
}
|
||||||
|
dc->DrawRectangle(pt.x, pt.y, m_width, m_height);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// wxRICHTEXT_USE_OWN_CARET
|
||||||
#endif
|
#endif
|
||||||
// wxUSE_RICHTEXT
|
// wxUSE_RICHTEXT
|
||||||
|
Reference in New Issue
Block a user