Changed a way how caret is painted in X11 - results in more snappy feeling

git-svn-id: svn://ultimatepp.org/upp/trunk@813 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2009-01-27 11:06:35 +00:00
parent e95f41157c
commit f0082dec32
6 changed files with 43 additions and 75 deletions

View file

@ -5,4 +5,3 @@ using namespace Upp;
GUI_APP_MAIN
{
}

View file

@ -313,18 +313,24 @@ bool Ctrl::IsModified() const
void Ctrl::SetCaret(int x, int y, int cx, int cy)
{
#ifdef PLATFORM_X11
if(this == caretCtrl)
RefreshCaret();
#endif
caretx = x;
carety = y;
caretcx = cx;
caretcy = cy;
#ifdef PLATFORM_X11
WndCaretTime = GetTickCount();
if(this == caretCtrl)
RefreshCaret();
#endif
}
void Ctrl::SetCaret(const Rect& r)
{
caretx = r.left;
carety = r.top;
caretcx = r.GetWidth();
caretcy = r.GetHeight();
SetCaret(r.left, r.top, r.GetWidth(), r.GetHeight());
}
Rect Ctrl::GetCaret() const

View file

@ -538,6 +538,7 @@ private:
void RefreshAccessKeysDo(bool vis);
static void DefferedFocusSync();
static void SyncCaret();
static void RefreshCaret();
static bool DispatchKey(dword keycode, int count);
void SetFocusWnd();
void KillFocusWnd();
@ -556,6 +557,7 @@ private:
Rect GetClippedView();
void ScrollRefresh(const Rect& r, int dx, int dy);
void SyncScroll();
void PaintCaret(Draw& w);
void CtrlPaint(Draw& w, const Rect& clip);
void RemoveFullRefresh();
bool PaintOpaqueAreas(Draw& w, const Rect& r, const Rect& clip, bool nochild = false);
@ -688,9 +690,7 @@ protected:
private:
static ArrayMap<Window, XWindow>& Xwindow();
static Ptr<Ctrl> WndCaretCtrl;
static int WndCaretTime;
static Rect WndCaretRect;
static bool WndCaretVisible;
static int Xbuttons;
static int Xbuttontime;
@ -704,7 +704,6 @@ private:
static void TimerAndPaint();
static void ProcessEvent(XEvent& event);
void Invalidate(XWindow& xw, const Rect& r);
static void XorCaret();
static void AnimateCaret();
void DoPaint(const Vector<Rect>& invalid);
void SetLastActive(XWindow *w, Ctrl *la);

View file

@ -234,6 +234,14 @@ struct sDrawLevelCheck {
#define DOLEVELCHECK
#endif
void Ctrl::PaintCaret(Draw& w)
{
#ifdef PLATFORM_X11
if(this == caretCtrl && WndCaretVisible)
w.DrawRect(caretx, carety, caretcx, caretcy, InvertColor);
#endif
}
void Ctrl::CtrlPaint(Draw& w, const Rect& clip) {
LEVELCHECK(w, this);
LTIMING("CtrlPaint");
@ -277,12 +285,14 @@ void Ctrl::CtrlPaint(Draw& w, const Rect& clip) {
w.Clip(oview);
w.Offset(view.left, view.top);
Paint(w);
PaintCaret(w);
w.End();
w.End();
}
else {
w.Clipoff(view);
Paint(w);
PaintCaret(w);
w.End();
}
}
@ -350,6 +360,7 @@ bool Ctrl::PaintOpaqueAreas(Draw& w, const Rect& r, const Rect& clip, bool nochi
{
LEVELCHECK(bw, this);
Paint(bw);
PaintCaret(bw);
}
bw.Put(w, opaque.TopLeft());
}
@ -360,6 +371,7 @@ bool Ctrl::PaintOpaqueAreas(Draw& w, const Rect& r, const Rect& clip, bool nochi
{
LEVELCHECK(w, this);
Paint(w);
PaintCaret(w);
}
w.End();
w.End();

View file

@ -278,7 +278,21 @@ void Ctrl::DefferedFocusSync()
}
}
void Ctrl::RefreshCaret()
{
if(caretCtrl)
caretCtrl->Refresh(caretCtrl->caretx, caretCtrl->carety,
caretCtrl->caretcx, caretCtrl->caretcy);
}
void Ctrl::SyncCaret() {
#ifdef PLATFORM_X11
if(focusCtrl != caretCtrl) {
RefreshCaret();
caretCtrl = focusCtrl;
RefreshCaret();
}
#else
Rect cr;
cr.Clear();
if(focusCtrl && focusCtrl->IsVisible()) {
@ -301,6 +315,7 @@ void Ctrl::SyncCaret() {
caretCtrl = focusCtrl;
caretRect = cr;
}
#endif
}
Ctrl *Ctrl::GetActiveWindow()

View file

@ -40,9 +40,7 @@ ArrayMap<Window, Ctrl::XWindow>& Ctrl::Xwindow()
return Single< ArrayMap<Window, XWindow> >();
}
Ptr<Ctrl> Ctrl::WndCaretCtrl;
int Ctrl::WndCaretTime;
Rect Ctrl::WndCaretRect;
bool Ctrl::WndCaretVisible;
int Ctrl::Xbuttons;
Window Ctrl::grabWindow, Ctrl::focusWindow;
@ -60,15 +58,6 @@ void Ctrl::DoPaint(const Vector<Rect>& invalid)
if(IsVisible()) {
LTIMING("DoPaint");
fullrefresh = false;
bool caret = false;
if(WndCaretCtrl == this && WndCaretVisible)
for(int i = 0; i < invalid.GetCount(); i++)
if(invalid[i].Intersects(WndCaretRect)) {
XorCaret();
XSync(Xdisplay, false);
caret = true;
break;
}
// if(GLX) return;
GC gc = XCreateGC(Xdisplay, (Drawable)top->window, 0, 0);
XftDraw *xftdraw = XftDrawCreate(Xdisplay, (Drawable) top->window,
@ -77,19 +66,12 @@ void Ctrl::DoPaint(const Vector<Rect>& invalid)
UpdateArea(draw, draw.GetClip());
XftDrawDestroy(xftdraw);
XFreeGC(Xdisplay, gc);
if(caret)
XorCaret();
}
}
void Ctrl::WndScrollView(const Rect& r, int dx, int dy)
{
if(r.IsEmpty() || !GetWindow()) return;
bool caret = false;
if(WndCaretCtrl == this && WndCaretVisible && r.Intersects(WndCaretRect)) {
caret = true;
XorCaret();
}
int cx = r.Width() - abs(dx);
int cy = r.Height() - abs(dy);
GC gc = XCreateGC(Xdisplay, GetWindow(), 0, 0);
@ -105,8 +87,6 @@ void Ctrl::WndScrollView(const Rect& r, int dx, int dy)
ur.Add(xw->invalid[i]);
for(int i = 0; i < ur.GetCount(); i++)
Invalidate(*xw, ur[i].Offseted(dx, dy));
if(caret)
XorCaret();
}
bool Ctrl::IsWaitingEvent()
@ -802,52 +782,15 @@ void Ctrl::FocusSync()
}
}
void Ctrl::XorCaret()
{
if(WndCaretCtrl && WndCaretCtrl->top && WndCaretCtrl->top->window) {
LTIMING("XorCaret");
// DLOG("XorCaret " << WndCaretRect << ", ctrl " << UPP::Name(WndCaretCtrl));
GC gc = XCreateGC(Xdisplay, WndCaretCtrl->top->window, 0, 0);
XSetFunction(Xdisplay, gc, GXinvert);
XFillRectangle(Xdisplay, WndCaretCtrl->top->window, gc,
WndCaretRect.left, WndCaretRect.top,
WndCaretRect.Width(), WndCaretRect.Height());
XFreeGC(Xdisplay, gc);
}
else
WndCaretCtrl = NULL;
}
void Ctrl::AnimateCaret()
{
if(WndCaretCtrl && WndCaretCtrl->top) {
int v = !(((GetTickCount() - WndCaretTime) / 500) & 1);
if(v != WndCaretVisible) {
XorCaret();
WndCaretVisible = v;
}
int v = !(((GetTickCount() - WndCaretTime) / 500) & 1);
if(v != WndCaretVisible) {
RefreshCaret();
WndCaretVisible = v;
}
}
void Ctrl::WndDestroyCaret()
{
LLOG("WndDestroyCaret vis: " << WndCaretVisible << ", ctrl: " << UPP::Name(WndCaretCtrl));
if(WndCaretVisible)
XorCaret();
WndCaretCtrl = NULL;
}
void Ctrl::WndCreateCaret(const Rect& cr)
{
LLOG("WndCreateCaret " << cr);
WndDestroyCaret();
WndCaretCtrl = this;
WndCaretRect = cr - GetRect().TopLeft();
WndCaretVisible = true;
WndCaretTime = GetTickCount();
XorCaret();
}
void Ctrl::Invalidate(XWindow& xw, const Rect& _r)
{
LTIMING("Invalidate");
@ -997,10 +940,6 @@ ViewDraw::ViewDraw(Ctrl *ctrl)
Rect r = ctrl->GetScreenView() - top->GetScreenRect().TopLeft();
Vector<Rect> clip;
clip.Add(r);
caret = Ctrl::WndCaretCtrl == ctrl && Ctrl::WndCaretVisible &&
r.Intersects(Ctrl::WndCaretRect);
if(caret)
Ctrl::XorCaret();
dw = top->GetWindow();
gc = XCreateGC(Xdisplay, dw, 0, 0);
#ifdef PLATFORM_XFT
@ -1013,8 +952,6 @@ ViewDraw::ViewDraw(Ctrl *ctrl)
ViewDraw::~ViewDraw()
{
XFreeGC(Xdisplay, gc);
if(caret)
Ctrl::XorCaret();
}
#endif