Added on-demand image loading option to wxRTC.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76110 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart 2014-03-10 11:08:42 +00:00
parent 3772880ce6
commit cd3fc53163
7 changed files with 420 additions and 21 deletions

View File

@ -34,6 +34,7 @@ All (GUI):
- Send events when toggling wxPropertyGrid nodes from keyboard (Armel Asselin).
- Fix wxRearrangeList::Check() which asserted and misbehaved before.
- Optimized wxRTC insertion and deletion when floating objects are present.
- Added on-demand image loading option to wxRTC.
wxGTK:

View File

@ -2211,7 +2211,8 @@ public:
*/
wxRichTextDrawingContext(wxRichTextBuffer* buffer);
void Init() { m_buffer = NULL; m_enableVirtualAttributes = true; m_enableImages = true; m_layingOut = false; }
void Init()
{ m_buffer = NULL; m_enableVirtualAttributes = true; m_enableImages = true; m_layingOut = false; m_enableDelayedImageLoading = false; }
/**
Does this object have virtual attributes?
@ -2293,9 +2294,22 @@ public:
bool GetLayingOut() const { return m_layingOut; }
/**
Enable or disable delayed image loading
*/
void EnableDelayedImageLoading(bool b) { m_enableDelayedImageLoading = b; }
/**
Returns @true if delayed image loading is enabled.
*/
bool GetDelayedImageLoading() const { return m_enableDelayedImageLoading; }
wxRichTextBuffer* m_buffer;
bool m_enableVirtualAttributes;
bool m_enableImages;
bool m_enableDelayedImageLoading;
bool m_layingOut;
};
@ -2428,7 +2442,6 @@ public:
virtual bool Merge(wxRichTextObject* WXUNUSED(object), wxRichTextDrawingContext& WXUNUSED(context)) { return false; }
/**
JACS
Returns @true if this object can potentially be split, by virtue of having
different virtual attributes for individual sub-objects.
*/
@ -4742,6 +4755,8 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextImage: public wxRichTextObject
{
DECLARE_DYNAMIC_CLASS(wxRichTextImage)
public:
enum { ImageState_Unloaded, ImageState_Loaded, ImageState_Bad };
// Constructors
/**
@ -4824,12 +4839,12 @@ public:
/**
Sets the image cache.
*/
void SetImageCache(const wxBitmap& bitmap) { m_imageCache = bitmap; m_originalImageSize = wxSize(bitmap.GetWidth(), bitmap.GetHeight()); }
void SetImageCache(const wxBitmap& bitmap) { m_imageCache = bitmap; m_originalImageSize = wxSize(bitmap.GetWidth(), bitmap.GetHeight()); m_imageState = ImageState_Loaded; }
/**
Resets the image cache.
*/
void ResetImageCache() { m_imageCache = wxNullBitmap; m_originalImageSize = wxSize(-1, -1); }
void ResetImageCache() { m_imageCache = wxNullBitmap; m_originalImageSize = wxSize(-1, -1); m_imageState = ImageState_Unloaded; }
/**
Returns the image block containing the raw data.
@ -4851,7 +4866,12 @@ public:
/**
Creates a cached image at the required size.
*/
virtual bool LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context, bool resetCache = false, const wxSize& parentSize = wxDefaultSize);
virtual bool LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context, wxSize& retImageSize, bool resetCache = false, const wxSize& parentSize = wxDefaultSize);
/**
Do the loading and scaling
*/
virtual bool LoadAndScaleImageCache(wxImage& image, const wxSize& sz, bool delayLoading, bool& changed);
/**
Gets the original image size.
@ -4863,10 +4883,21 @@ public:
*/
void SetOriginalImageSize(const wxSize& sz) { m_originalImageSize = sz; }
/**
Gets the image state.
*/
int GetImageState() const { return m_imageState; }
/**
Sets the image state.
*/
void SetImageState(int state) { m_imageState = state; }
protected:
wxRichTextImageBlock m_imageBlock;
wxBitmap m_imageCache;
wxSize m_originalImageSize;
int m_imageState;
};
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextCommand;

View File

@ -17,7 +17,7 @@
#include "wx/scrolwin.h"
#include "wx/caret.h"
#include "wx/timer.h"
#include "wx/textctrl.h"
#if wxUSE_DRAG_AND_DROP
@ -79,6 +79,8 @@ class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextStyleDefinition;
#define wxRICHTEXT_DEFAULT_DELAYED_LAYOUT_THRESHOLD 20000
// Milliseconds before layout occurs after resize
#define wxRICHTEXT_DEFAULT_LAYOUT_INTERVAL 50
// Milliseconds before delayed image processing occurs
#define wxRICHTEXT_DEFAULT_DELAYED_IMAGE_PROCESSING_INTERVAL 200
/* Identifiers
*/
@ -1980,6 +1982,12 @@ public:
*/
bool RefreshForSelectionChange(const wxRichTextSelection& oldSelection, const wxRichTextSelection& newSelection);
/**
Overrides standard refresh in order to provoke delayed image loading.
*/
virtual void Refresh( bool eraseBackground = true,
const wxRect *rect = (const wxRect *) NULL );
/**
Sets the caret position.
@ -2134,6 +2142,38 @@ public:
bool GetImagesEnabled() const { return m_enableImages; }
/**
Enable or disable delayed image loading
*/
void EnableDelayedImageLoading(bool b) { m_enableDelayedImageLoading = b; }
/**
Returns @true if delayed image loading is enabled.
*/
bool GetDelayedImageLoading() const { return m_enableDelayedImageLoading; }
/**
Gets the flag indicating that delayed image processing is required.
*/
bool GetDelayedImageProcessingRequired() const { return m_delayedImageProcessingRequired; }
/**
Sets the flag indicating that delayed image processing is required.
*/
void SetDelayedImageProcessingRequired(bool b) { m_delayedImageProcessingRequired = b; }
/**
Returns the last time delayed image processing was performed.
*/
wxLongLong GetDelayedImageProcessingTime() const { return m_delayedImageProcessingTime; }
/**
Sets the last time delayed image processing was performed.
*/
void SetDelayedImageProcessingTime(wxLongLong t) { m_delayedImageProcessingTime = t; }
#ifdef DOXYGEN
/**
Returns the content of the entire control as a string.
@ -2209,6 +2249,22 @@ public:
// implement wxTextEntry methods
virtual wxString DoGetValue() const;
/**
Do delayed image loading and garbage-collect other images
*/
bool ProcessDelayedImageLoading(bool refresh);
bool ProcessDelayedImageLoading(const wxRect& screenRect, wxRichTextParagraphLayoutBox* box, int& loadCount);
/**
Request delayed image processing.
*/
void RequestDelayedImageProcessing();
/**
Respond to timer events.
*/
void OnTimer(wxTimerEvent& event);
protected:
// implement the wxTextEntry pure virtual method
virtual wxWindow *GetEditableWindow() { return this; }
@ -2336,6 +2392,12 @@ protected:
/// Whether images are enabled for this control
bool m_enableImages;
/// Whether delayed image loading is enabled for this control
bool m_enableDelayedImageLoading;
bool m_delayedImageProcessingRequired;
wxLongLong m_delayedImageProcessingTime;
wxTimer m_delayedImageProcessingTimer;
};
#if wxUSE_DRAG_AND_DROP

View File

@ -2123,9 +2123,35 @@ public:
bool GetImagesEnabled() const { return m_enableImages; }
/**
Set laying out flag
*/
void SetLayingOut(bool b) { m_layingOut = b; }
/**
Returns @true if laying out.
*/
bool GetLayingOut() const { return m_layingOut; }
/**
Enable or disable delayed image loading
*/
void EnableDelayedImageLoading(bool b) { m_enableDelayedImageLoading = b; }
/**
Returns @true if delayed image loading is enabled.
*/
bool GetDelayedImageLoading() const { return m_enableDelayedImageLoading; }
wxRichTextBuffer* m_buffer;
bool m_enableVirtualAttributes;
bool m_enableImages;
bool m_enableDelayedImageLoading;
bool m_layingOut;
};
/**
@ -4671,11 +4697,38 @@ public:
/**
Creates a cached image at the required size.
*/
virtual bool LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context, bool resetCache = false, const wxSize& parentSize = wxDefaultSize);
virtual bool LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context, wxSize& retImageSize, bool resetCache = false, const wxSize& parentSize = wxDefaultSize);
/**
Do the loading and scaling
*/
virtual bool LoadAndScaleImageCache(wxImage& image, const wxSize& sz, bool delayLoading, bool& changed);
/**
Gets the original image size.
*/
wxSize GetOriginalImageSize() const { return m_originalImageSize; }
/**
Sets the original image size.
*/
void SetOriginalImageSize(const wxSize& sz) { m_originalImageSize = sz; }
/**
Gets the image state.
*/
int GetImageState() const { return m_imageState; }
/**
Sets the image state.
*/
void SetImageState(int state) { m_imageState = state; }
protected:
wxRichTextImageBlock m_imageBlock;
wxBitmap m_imageCache;
wxSize m_originalImageSize;
int m_imageState;
};
class wxRichTextCommand;

View File

@ -55,6 +55,8 @@
#define wxRICHTEXT_DEFAULT_DELAYED_LAYOUT_THRESHOLD 20000
// Milliseconds before layout occurs after resize
#define wxRICHTEXT_DEFAULT_LAYOUT_INTERVAL 50
// Milliseconds before delayed image processing occurs
#define wxRICHTEXT_DEFAULT_DELAYED_IMAGE_PROCESSING_INTERVAL 200
/* Identifiers
*/
@ -2044,6 +2046,38 @@ public:
bool GetImagesEnabled() const;
/**
Enable or disable delayed image loading
*/
void EnableDelayedImageLoading(bool b) { m_enableDelayedImageLoading = b; }
/**
Returns @true if delayed image loading is enabled.
*/
bool GetDelayedImageLoading() const { return m_enableDelayedImageLoading; }
/**
Gets the flag indicating that delayed image processing is required.
*/
bool GetDelayedImageProcessingRequired() const { return m_delayedImageProcessingRequired; }
/**
Sets the flag indicating that delayed image processing is required.
*/
void SetDelayedImageProcessingRequired(bool b) { m_delayedImageProcessingRequired = b; }
/**
Returns the last time delayed image processing was performed.
*/
wxLongLong GetDelayedImageProcessingTime() const { return m_delayedImageProcessingTime; }
/**
Sets the last time delayed image processing was performed.
*/
void SetDelayedImageProcessingTime(wxLongLong t) { m_delayedImageProcessingTime = t; }
/**
Returns the caret position since the default formatting was changed. As
soon as this position changes, we no longer reflect the default style
@ -2137,6 +2171,22 @@ public:
// implement wxTextEntry methods
virtual wxString DoGetValue() const;
/**
Do delayed image loading and garbage-collect other images
*/
bool ProcessDelayedImageLoading(bool refresh);
bool ProcessDelayedImageLoading(const wxRect& screenRect, wxRichTextParagraphLayoutBox* box, int& loadCount);
/**
Request delayed image processing.
*/
void RequestDelayedImageProcessing();
/**
Respond to timer events.
*/
void OnTimer(wxTimerEvent& event);
protected:
// implement the wxTextEntry pure virtual method
virtual wxWindow *GetEditableWindow();
@ -2220,6 +2270,23 @@ protected:
/// The object that currently has the editing focus
wxRichTextParagraphLayoutBox* m_focusObject;
/// An overall scale factor
double m_scale;
/// Variables for scrollbar hysteresis detection
wxSize m_lastWindowSize;
int m_setupScrollbarsCount;
int m_setupScrollbarsCountInOnSize;
/// Whether images are enabled for this control
bool m_enableImages;
/// Whether delayed image loading is enabled for this control
bool m_enableDelayedImageLoading;
bool m_delayedImageProcessingRequired;
wxLongLong m_delayedImageProcessingTime;
wxTimer m_delayedImageProcessingTimer;
};
/**

View File

@ -5150,7 +5150,8 @@ bool wxRichTextParagraph::Layout(wxDC& dc, wxRichTextDrawingContext& context, co
}
while (doLoop);
if (child->IsTopLevel())
// 2014-03-08: also need to set object positions
//if (child->IsTopLevel())
{
// We can move it to the correct position at this point
// TODO: probably need to add margin
@ -12213,17 +12214,24 @@ wxRichTextImage::~wxRichTextImage()
void wxRichTextImage::Init()
{
m_originalImageSize = wxSize(-1, -1);
m_imageState = ImageState_Unloaded;
}
/// Create a cached image at the required size
bool wxRichTextImage::LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context, bool resetCache, const wxSize& parentSize)
bool wxRichTextImage::LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context, wxSize& retImageSize, bool resetCache, const wxSize& parentSize)
{
if (!m_imageBlock.IsOk())
{
m_imageState = ImageState_Bad;
return false;
}
// Don't repeat unless absolutely necessary
if (m_imageCache.IsOk() && !resetCache && !context.GetLayingOut())
{
retImageSize = wxSize(m_imageCache.GetWidth(), m_imageCache.GetHeight());
return true;
}
if (!context.GetImagesEnabled())
{
@ -12231,7 +12239,9 @@ bool wxRichTextImage::LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context
{
wxBitmap bitmap(image_placeholder24x24_xpm);
m_imageCache = bitmap;
m_imageState = ImageState_Loaded;
}
retImageSize = wxSize(m_imageCache.GetWidth(), m_imageCache.GetHeight());
return true;
}
@ -12243,13 +12253,15 @@ bool wxRichTextImage::LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context
if (resetCache || m_originalImageSize.GetWidth() <= 0 || m_originalImageSize.GetHeight() <= 0)
{
m_imageCache = wxNullBitmap;
m_imageState = ImageState_Unloaded;
m_imageBlock.Load(image);
if (!image.IsOk())
if (!m_imageBlock.Load(image) || !image.IsOk())
{
wxBitmap bitmap(image_placeholder24x24_xpm);
m_imageCache = bitmap;
m_originalImageSize = wxSize(bitmap.GetWidth(), bitmap.GetHeight());
m_imageState = ImageState_Bad;
retImageSize = wxSize(m_imageCache.GetWidth(), m_imageCache.GetHeight());
return false;
}
@ -12359,24 +12371,49 @@ bool wxRichTextImage::LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context
width = wxMax(1, width);
height = wxMax(1, height);
retImageSize = wxSize(width, height);
bool changed = false;
return LoadAndScaleImageCache(image, retImageSize, context.GetDelayedImageLoading(), changed);
}
// Do the loading and scaling
bool wxRichTextImage::LoadAndScaleImageCache(wxImage& image, const wxSize& sz, bool delayLoading, bool& changed)
{
int width = sz.x;
int height = sz.y;
if (m_imageCache.IsOk() && m_imageCache.GetWidth() == width && m_imageCache.GetHeight() == height)
{
// Do nothing, we didn't need to change the image cache
changed = false;
}
else
{
changed = true;
if (delayLoading)
{
if (m_imageCache.IsOk())
m_imageCache = wxNullBitmap;
m_imageState = ImageState_Unloaded;
return true;
}
if (!image.IsOk())
{
m_imageBlock.Load(image);
if (!image.IsOk())
if (!m_imageBlock.Load(image) || !image.IsOk())
{
wxBitmap bitmap(image_placeholder24x24_xpm);
m_imageCache = bitmap;
m_originalImageSize = wxSize(bitmap.GetWidth(), bitmap.GetHeight());
m_imageState = ImageState_Bad;
return false;
}
}
m_originalImageSize = wxSize(image.GetWidth(), image.GetHeight());
if (image.GetWidth() == width && image.GetHeight() == height)
m_imageCache = wxBitmap(image);
else
@ -12397,6 +12434,11 @@ bool wxRichTextImage::LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context
}
}
if (m_imageCache.IsOk())
m_imageState = ImageState_Loaded;
else
m_imageState = ImageState_Bad;
return m_imageCache.IsOk();
}
@ -12406,9 +12448,6 @@ bool wxRichTextImage::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wx
if (!IsShown())
return true;
if (!m_imageCache.IsOk())
return false;
wxRichTextAttr attr(GetAttributes());
AdjustAttributes(attr, context);
@ -12419,7 +12458,14 @@ bool wxRichTextImage::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wx
marginRect = rect; // outer rectangle, will calculate contentRect
GetBoxRects(dc, GetBuffer(), attr, marginRect, borderRect, contentRect, paddingRect, outlineRect);
dc.DrawBitmap(m_imageCache, contentRect.x, contentRect.y, true);
if (m_imageCache.IsOk())
dc.DrawBitmap(m_imageCache, contentRect.x, contentRect.y, true);
else
{
dc.SetPen(*wxLIGHT_GREY_PEN);
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRectangle(contentRect);
}
if (selection.WithinSelection(GetRange().GetStart(), this))
{
@ -12436,10 +12482,10 @@ bool wxRichTextImage::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wx
/// Lay the item out
bool wxRichTextImage::Layout(wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& parentRect, int WXUNUSED(style))
{
if (!LoadImageCache(dc, context, false, parentRect.GetSize()))
wxSize imageSize;
if (!LoadImageCache(dc, context, imageSize, false, parentRect.GetSize()))
return false;
wxSize imageSize(m_imageCache.GetWidth(), m_imageCache.GetHeight());
wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
contentRect = wxRect(wxPoint(0,0), imageSize);
@ -12465,7 +12511,8 @@ bool wxRichTextImage::GetRangeSize(const wxRichTextRange& range, wxSize& size, i
if (!range.IsWithin(GetRange()))
return false;
if (!((wxRichTextImage*)this)->LoadImageCache(dc, context, false, parentSize))
wxSize imageSize;
if (!((wxRichTextImage*)this)->LoadImageCache(dc, context, imageSize, false, parentSize))
{
size.x = 0; size.y = 0;
if (partialExtents)
@ -12476,7 +12523,6 @@ bool wxRichTextImage::GetRangeSize(const wxRichTextRange& range, wxSize& size, i
wxRichTextAttr attr(GetAttributes());
((wxRichTextObject*)this)->AdjustAttributes(attr, context);
wxSize imageSize(m_imageCache.GetWidth(), m_imageCache.GetHeight());
wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
contentRect = wxRect(wxPoint(0,0), imageSize);
GetBoxRects(dc, GetBuffer(), attr, marginRect, borderRect, contentRect, paddingRect, outlineRect);
@ -15040,6 +15086,7 @@ wxRichTextDrawingContext::wxRichTextDrawingContext(wxRichTextBuffer* buffer)
{
EnableVirtualAttributes(m_buffer->GetRichTextCtrl()->GetVirtualAttributesEnabled());
m_enableImages = m_buffer->GetRichTextCtrl()->GetImagesEnabled();
m_enableDelayedImageLoading = m_buffer->GetRichTextCtrl()->GetDelayedImageLoading();
}
}

View File

@ -177,6 +177,7 @@ BEGIN_EVENT_TABLE( wxRichTextCtrl, wxControl )
EVT_MOUSE_CAPTURE_LOST(wxRichTextCtrl::OnCaptureLost)
EVT_CONTEXT_MENU(wxRichTextCtrl::OnContextMenu)
EVT_SYS_COLOUR_CHANGED(wxRichTextCtrl::OnSysColourChanged)
EVT_TIMER(wxID_ANY, wxRichTextCtrl::OnTimer)
EVT_MENU(wxID_UNDO, wxRichTextCtrl::OnUndo)
EVT_UPDATE_UI(wxID_UNDO, wxRichTextCtrl::OnUpdateUndo)
@ -350,6 +351,8 @@ wxRichTextCtrl::~wxRichTextCtrl()
GetBuffer().RemoveEventHandler(this);
delete m_contextMenu;
m_delayedImageProcessingTimer.Stop();
}
/// Member initialisation
@ -382,6 +385,10 @@ void wxRichTextCtrl::Init()
m_setupScrollbarsCountInOnSize = 0;
m_enableImages = true;
m_enableDelayedImageLoading = false;
m_delayedImageProcessingRequired = false;
m_delayedImageProcessingTime = 0;
}
void wxRichTextCtrl::DoThaw()
@ -2602,6 +2609,9 @@ void wxRichTextCtrl::OnSize(wxSizeEvent& event)
// OnSize was the source of a scrollbar change.
m_setupScrollbarsCountInOnSize = m_setupScrollbarsCount;
if (GetDelayedImageLoading())
RequestDelayedImageProcessing();
event.Skip();
}
@ -2642,6 +2652,16 @@ void wxRichTextCtrl::OnIdle(wxIdleEvent& event)
Refresh(false);
}
const int imageProcessingInterval = wxRICHTEXT_DEFAULT_DELAYED_IMAGE_PROCESSING_INTERVAL;
if (m_enableDelayedImageLoading && m_delayedImageProcessingRequired && (wxGetLocalTimeMillis() > (m_delayedImageProcessingTime + imageProcessingInterval)))
{
m_delayedImageProcessingTimer.Stop();
m_delayedImageProcessingRequired = false;
m_delayedImageProcessingTime = 0;
ProcessDelayedImageLoading(true);
}
if (m_caretPositionForDefaultStyle != -2)
{
// If the caret position has changed, no longer reflect the default style
@ -4045,6 +4065,9 @@ bool wxRichTextCtrl::LayoutContent(bool onlyVisibleRect)
if (!IsFrozen() && !onlyVisibleRect)
SetupScrollbars();
if (GetDelayedImageLoading())
RequestDelayedImageProcessing();
}
return true;
@ -4668,6 +4691,15 @@ bool wxRichTextCtrl::RefreshForSelectionChange(const wxRichTextSelection& oldSel
return true;
}
// Overrides standard refresh in order to provoke delayed image loading.
void wxRichTextCtrl::Refresh( bool eraseBackground, const wxRect *rect)
{
if (GetDelayedImageLoading())
RequestDelayedImageProcessing();
wxWindow::Refresh(eraseBackground, rect);
}
// margins functions
bool wxRichTextCtrl::DoSetMargins(const wxPoint& pt)
{
@ -4906,6 +4938,112 @@ wxRect wxRichTextCtrl::GetScaledRect(const wxRect& rect) const
(int) (0.5 + double(rect.width) * GetScale()), (int) (0.5 + double(rect.height) * GetScale()));
}
// Do delayed image loading and garbage-collect other images
bool wxRichTextCtrl::ProcessDelayedImageLoading(bool refresh)
{
int loadCount = 0;
wxSize clientSize = GetUnscaledSize(GetClientSize());
wxPoint firstVisiblePt = GetUnscaledPoint(GetFirstVisiblePoint());
wxRect screenRect(firstVisiblePt, clientSize);
// Expand screen rect so that we actually process images in the vicinity,
// for smoother paging and scrolling.
screenRect.y -= (clientSize.y*3);
screenRect.height += (clientSize.y*6);
ProcessDelayedImageLoading(screenRect, & GetBuffer(), loadCount);
if (loadCount > 0 && refresh)
{
wxWindow::Refresh(false);
}
return loadCount > 0;
}
bool wxRichTextCtrl::ProcessDelayedImageLoading(const wxRect& screenRect, wxRichTextParagraphLayoutBox* box, int& loadCount)
{
if (!box || !box->IsShown())
return true;
wxRichTextObjectList::compatibility_iterator node = box->GetChildren().GetFirst();
while (node)
{
// Could be a cell or a paragraph
wxRichTextCompositeObject* composite = wxDynamicCast(node->GetData(), wxRichTextCompositeObject);
if (composite->IsTopLevel())
ProcessDelayedImageLoading(screenRect, wxDynamicCast(composite, wxRichTextParagraphLayoutBox), loadCount);
else // assume a paragraph
{
wxRichTextObjectList::compatibility_iterator node2 = composite->GetChildren().GetFirst();
while (node2)
{
wxRichTextObject* obj = node2->GetData();
if (obj->IsTopLevel())
ProcessDelayedImageLoading(screenRect, wxDynamicCast(obj, wxRichTextParagraphLayoutBox), loadCount);
else
{
wxRichTextImage* imageObj = wxDynamicCast(obj, wxRichTextImage);
if (imageObj && imageObj->IsShown())
{
const wxRect& rect(imageObj->GetRect());
if ((rect.GetBottom() < screenRect.GetTop()) || (rect.GetTop() > screenRect.GetBottom()))
{
// Off-screen
imageObj->ResetImageCache();
}
else
{
// On-screen
wxRichTextDrawingContext context(& GetBuffer());
context.SetLayingOut(true);
context.EnableDelayedImageLoading(false);
wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
marginRect = imageObj->GetRect(); // outer rectangle, will calculate contentRect
if (marginRect.GetSize() != wxDefaultSize)
{
wxClientDC dc(this);
wxRichTextAttr attr(imageObj->GetAttributes());
imageObj->AdjustAttributes(attr, context);
imageObj->GetBoxRects(dc, & GetBuffer(), attr, marginRect, borderRect, contentRect, paddingRect, outlineRect);
wxImage image;
bool changed = false;
if (imageObj->LoadAndScaleImageCache(image, contentRect.GetSize(), false, changed) && changed)
{
loadCount ++;
}
}
}
}
}
node2 = node2->GetNext();
}
}
node = node->GetNext();
}
return true;
}
void wxRichTextCtrl::RequestDelayedImageProcessing()
{
SetDelayedImageProcessingRequired(true);
SetDelayedImageProcessingTime(wxGetLocalTimeMillis());
m_delayedImageProcessingTimer.SetOwner(this, GetId());
m_delayedImageProcessingTimer.Start(wxRICHTEXT_DEFAULT_DELAYED_IMAGE_PROCESSING_INTERVAL);
}
void wxRichTextCtrl::OnTimer(wxTimerEvent& event)
{
if (event.GetId() == GetId())
wxWakeUpIdle();
else
event.Skip();
}
#if wxRICHTEXT_USE_OWN_CARET
// ----------------------------------------------------------------------------