Reduce flicker with STC call tips in MSW

When switching between call tips in MSW, there can be a bit of flicker
when the first is closed and the new one is opened. To reduce the
flicker, store the call tip background in a bitmap and use a very brief
fade-in animation when showing the new call tip.
This commit is contained in:
New Pagodi
2019-03-10 22:10:09 -05:00
parent 0f7552cdb0
commit f0ba9f0ef1
2 changed files with 59 additions and 6 deletions

View File

@@ -2094,7 +2094,10 @@ PRectangle Window::GetMonitorRect(Point pt) {
if ( show )
{
HWND hWnd = reinterpret_cast<HWND>(GetHandle());
::ShowWindow(hWnd, SW_SHOWNA );
if ( GetName() == "wxSTCCallTip" )
::AnimateWindow(hWnd, 25, AW_BLEND);
else
::ShowWindow(hWnd, SW_SHOWNA );
::SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

View File

@@ -99,12 +99,38 @@ public:
wxSTCPopupWindow(parent), m_ct(ct), m_swx(swx)
{
Bind(wxEVT_LEFT_DOWN, &wxSTCCallTip::OnLeftDown, this);
Bind(wxEVT_SIZE, &wxSTCCallTip::OnSize, this);
Bind(wxEVT_PAINT, &wxSTCCallTip::OnPaint, this);
#ifdef __WXMSW__
Bind(wxEVT_ERASE_BACKGROUND, &wxSTCCallTip::OnEraseBackground, this);
SetBackgroundStyle(wxBG_STYLE_ERASE);
#else
SetBackgroundStyle(wxBG_STYLE_PAINT);
#endif
SetName("wxSTCCallTip");
}
void DrawBack(const wxSize& size)
{
m_back = wxBitmap(size);
wxMemoryDC mem(m_back);
Surface* surfaceWindow = Surface::Allocate(m_swx->technology);
surfaceWindow->Init(&mem, m_ct->wDraw.GetID());
m_ct->PaintCT(surfaceWindow);
surfaceWindow->Release();
delete surfaceWindow;
}
virtual void Refresh(bool eraseBg=true, const wxRect *rect=NULL) wxOVERRIDE
{
if ( rect == NULL )
DrawBack(GetSize());
wxSTCPopupWindow::Refresh(eraseBg, rect);
}
void OnLeftDown(wxMouseEvent& event)
{
wxPoint pt = event.GetPosition();
@@ -113,19 +139,43 @@ public:
m_swx->CallTipClick();
}
void OnSize(wxSizeEvent& event)
{
DrawBack(event.GetSize());
event.Skip();
}
#ifdef __WXMSW__
void OnPaint(wxPaintEvent& WXUNUSED(evt))
{
wxRect upd = GetUpdateClientRect();
wxMemoryDC mem(m_back);
wxPaintDC dc(this);
dc.Blit(upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight(), &mem,
upd.GetX(), upd.GetY());
}
void OnEraseBackground(wxEraseEvent& event)
{
event.GetDC()->DrawBitmap(m_back, 0, 0);
}
#else
void OnPaint(wxPaintEvent& WXUNUSED(evt))
{
wxAutoBufferedPaintDC dc(this);
Surface* surfaceWindow = Surface::Allocate(m_swx->technology);
surfaceWindow->Init(&dc, m_ct->wDraw.GetID());
m_ct->PaintCT(surfaceWindow);
surfaceWindow->Release();
delete surfaceWindow;
dc.DrawBitmap(m_back, 0, 0);
}
#endif // __WXMSW__
private:
CallTip* m_ct;
ScintillaWX* m_swx;
wxBitmap m_back;
};