mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-07 12:32:26 +00:00
Do the actual drawing in the paint event
Historically, because of two-stage drawing, LyX has been painting on a Pixmap, and this pixmap is copied to screen at paint event time. Now that we have three-stage drawing, it is possible to delay the painting to actual paint event and avoid the intermediate Pixmap. Known bug: the cursor is never erased.
This commit is contained in:
parent
efc7359015
commit
24c29908bd
@ -246,7 +246,7 @@ SyntheticMouseEvent::SyntheticMouseEvent()
|
|||||||
|
|
||||||
|
|
||||||
GuiWorkArea::Private::Private(GuiWorkArea * parent)
|
GuiWorkArea::Private::Private(GuiWorkArea * parent)
|
||||||
: p(parent), screen_(0), buffer_view_(0), lyx_view_(0),
|
: p(parent), buffer_view_(0), lyx_view_(0),
|
||||||
cursor_visible_(false), cursor_(0),
|
cursor_visible_(false), cursor_(0),
|
||||||
need_resize_(false), schedule_redraw_(false), preedit_lines_(1),
|
need_resize_(false), schedule_redraw_(false), preedit_lines_(1),
|
||||||
pixel_ratio_(1.0),
|
pixel_ratio_(1.0),
|
||||||
@ -297,7 +297,6 @@ void GuiWorkArea::init()
|
|||||||
d->cursor_timeout_.setInterval(500);
|
d->cursor_timeout_.setInterval(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
d->resetScreen();
|
|
||||||
// With Qt4.5 a mouse event will happen before the first paint event
|
// With Qt4.5 a mouse event will happen before the first paint event
|
||||||
// so make sure that the buffer view has an up to date metrics.
|
// so make sure that the buffer view has an up to date metrics.
|
||||||
d->buffer_view_->resize(viewport()->width(), viewport()->height());
|
d->buffer_view_->resize(viewport()->width(), viewport()->height());
|
||||||
@ -311,10 +310,11 @@ void GuiWorkArea::init()
|
|||||||
setFrameStyle(QFrame::NoFrame);
|
setFrameStyle(QFrame::NoFrame);
|
||||||
updateWindowTitle();
|
updateWindowTitle();
|
||||||
|
|
||||||
viewport()->setAutoFillBackground(false);
|
//viewport()->setAutoFillBackground(false);
|
||||||
// We don't need double-buffering nor SystemBackground on
|
// We don't need double-buffering nor SystemBackground on
|
||||||
// the viewport because we have our own backing pixmap.
|
// the viewport because we have our own backing pixmap.
|
||||||
viewport()->setAttribute(Qt::WA_NoSystemBackground);
|
//viewport()->setAttribute(Qt::WA_NoSystemBackground);
|
||||||
|
viewport()->setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
|
||||||
setFocusPolicy(Qt::StrongFocus);
|
setFocusPolicy(Qt::StrongFocus);
|
||||||
|
|
||||||
@ -342,7 +342,6 @@ GuiWorkArea::~GuiWorkArea()
|
|||||||
try {
|
try {
|
||||||
d->buffer_view_->buffer().workAreaManager().remove(this);
|
d->buffer_view_->buffer().workAreaManager().remove(this);
|
||||||
} catch(...) {}
|
} catch(...) {}
|
||||||
delete d->screen_;
|
|
||||||
delete d->buffer_view_;
|
delete d->buffer_view_;
|
||||||
delete d->cursor_;
|
delete d->cursor_;
|
||||||
// Completer has a QObject parent and is thus automatically destroyed.
|
// Completer has a QObject parent and is thus automatically destroyed.
|
||||||
@ -489,8 +488,7 @@ void GuiWorkArea::redraw(bool update_metrics)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LYXERR(Debug::WORKAREA, "WorkArea::redraw screen");
|
LYXERR(Debug::WORKAREA, "WorkArea::redraw screen");
|
||||||
d->updateScreen();
|
viewport()->update();
|
||||||
update(0, 0, viewport()->width(), viewport()->height());
|
|
||||||
|
|
||||||
/// \warning: scrollbar updating *must* be done after the BufferView is drawn
|
/// \warning: scrollbar updating *must* be done after the BufferView is drawn
|
||||||
/// because \c BufferView::updateScrollbar() is called in \c BufferView::draw().
|
/// because \c BufferView::updateScrollbar() is called in \c BufferView::draw().
|
||||||
@ -589,7 +587,7 @@ void GuiWorkArea::Private::resizeBufferView()
|
|||||||
buffer_view_->resize(p->viewport()->width(), p->viewport()->height());
|
buffer_view_->resize(p->viewport()->width(), p->viewport()->height());
|
||||||
if (cursor_in_view)
|
if (cursor_in_view)
|
||||||
buffer_view_->scrollToCursor();
|
buffer_view_->scrollToCursor();
|
||||||
updateScreen();
|
p->viewport()->update();
|
||||||
|
|
||||||
// Update scrollbars which might have changed due different
|
// Update scrollbars which might have changed due different
|
||||||
// BufferView dimension. This is especially important when the
|
// BufferView dimension. This is especially important when the
|
||||||
@ -1158,20 +1156,12 @@ void GuiWorkArea::resizeEvent(QResizeEvent * ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuiWorkArea::Private::update(int x, int y, int w, int h)
|
|
||||||
{
|
|
||||||
p->viewport()->update(x, y, w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GuiWorkArea::paintEvent(QPaintEvent * ev)
|
void GuiWorkArea::paintEvent(QPaintEvent * ev)
|
||||||
{
|
{
|
||||||
QRectF const rc = ev->rect();
|
|
||||||
// LYXERR(Debug::PAINTING, "paintEvent begin: x: " << rc.x()
|
// LYXERR(Debug::PAINTING, "paintEvent begin: x: " << rc.x()
|
||||||
// << " y: " << rc.y() << " w: " << rc.width() << " h: " << rc.height());
|
// << " y: " << rc.y() << " w: " << rc.width() << " h: " << rc.height());
|
||||||
|
|
||||||
if (d->needResize()) {
|
if (d->needResize()) {
|
||||||
d->resetScreen();
|
|
||||||
d->resizeBufferView();
|
d->resizeBufferView();
|
||||||
if (d->cursor_visible_) {
|
if (d->cursor_visible_) {
|
||||||
d->hideCursor();
|
d->hideCursor();
|
||||||
@ -1179,29 +1169,14 @@ void GuiWorkArea::paintEvent(QPaintEvent * ev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QPainter pain(viewport());
|
GuiPainter pain(viewport(), pixelRatio());
|
||||||
double const pr = pixelRatio();
|
d->buffer_view_->draw(pain);
|
||||||
QRectF const rcs = QRectF(rc.x() * pr, rc.y() * pr, rc.width() * pr, rc.height() * pr);
|
|
||||||
|
|
||||||
if (lyxrc.use_qimage) {
|
|
||||||
QImage const & image = static_cast<QImage const &>(*d->screen_);
|
|
||||||
pain.drawImage(rc, image, rcs);
|
|
||||||
} else {
|
|
||||||
QPixmap const & pixmap = static_cast<QPixmap const &>(*d->screen_);
|
|
||||||
pain.drawPixmap(rc, pixmap, rcs);
|
|
||||||
}
|
|
||||||
d->cursor_->draw(pain);
|
d->cursor_->draw(pain);
|
||||||
ev->accept();
|
ev->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuiWorkArea::Private::updateScreen()
|
|
||||||
{
|
|
||||||
GuiPainter pain(screen_, p->pixelRatio());
|
|
||||||
buffer_view_->draw(pain);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GuiWorkArea::Private::showCursor(int x, int y, int h,
|
void GuiWorkArea::Private::showCursor(int x, int y, int h,
|
||||||
bool l_shape, bool rtl, bool completable)
|
bool l_shape, bool rtl, bool completable)
|
||||||
{
|
{
|
||||||
@ -1211,9 +1186,8 @@ void GuiWorkArea::Private::showCursor(int x, int y, int h,
|
|||||||
// We can't use redraw() here because this would trigger a infinite
|
// We can't use redraw() here because this would trigger a infinite
|
||||||
// recursive loop with showCursor().
|
// recursive loop with showCursor().
|
||||||
buffer_view_->resize(p->viewport()->width(), p->viewport()->height());
|
buffer_view_->resize(p->viewport()->width(), p->viewport()->height());
|
||||||
updateScreen();
|
p->viewport()->update();
|
||||||
updateScrollbar();
|
updateScrollbar();
|
||||||
p->viewport()->update(QRect(0, 0, p->viewport()->width(), p->viewport()->height()));
|
|
||||||
schedule_redraw_ = false;
|
schedule_redraw_ = false;
|
||||||
// Show the cursor immediately after the update.
|
// Show the cursor immediately after the update.
|
||||||
hideCursor();
|
hideCursor();
|
||||||
@ -1237,6 +1211,10 @@ void GuiWorkArea::Private::removeCursor()
|
|||||||
|
|
||||||
void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
|
void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
|
||||||
{
|
{
|
||||||
|
//FIXME Broken Feature !!
|
||||||
|
// I do not think that we are supposed to paint inside this event. Shall we
|
||||||
|
// just let TextMetrics::breakRow add this to the relevant Row object?
|
||||||
|
#if 0
|
||||||
QString const & commit_string = e->commitString();
|
QString const & commit_string = e->commitString();
|
||||||
docstring const & preedit_string
|
docstring const & preedit_string
|
||||||
= qstring_to_ucs4(e->preeditString());
|
= qstring_to_ucs4(e->preeditString());
|
||||||
@ -1272,7 +1250,7 @@ void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
d->buffer_view_->updateMetrics();
|
d->buffer_view_->updateMetrics();
|
||||||
d->updateScreen();
|
viewport()->update();
|
||||||
// FIXME: shall we use real_current_font here? (see #10478)
|
// FIXME: shall we use real_current_font here? (see #10478)
|
||||||
FontInfo font = d->buffer_view_->cursor().getFont().fontInfo();
|
FontInfo font = d->buffer_view_->cursor().getFont().fontInfo();
|
||||||
FontMetrics const & fm = theFontMetrics(font);
|
FontMetrics const & fm = theFontMetrics(font);
|
||||||
@ -1281,7 +1259,7 @@ void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
|
|||||||
int cur_y = d->cursor_->rect().bottom();
|
int cur_y = d->cursor_->rect().bottom();
|
||||||
|
|
||||||
// redraw area of preedit string.
|
// redraw area of preedit string.
|
||||||
update(0, cur_y - height, viewport()->width(),
|
viewport()->update(0, cur_y - height, viewport()->width(),
|
||||||
(height + 1) * d->preedit_lines_);
|
(height + 1) * d->preedit_lines_);
|
||||||
|
|
||||||
if (preedit_string.empty()) {
|
if (preedit_string.empty()) {
|
||||||
@ -1369,8 +1347,9 @@ void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update the preedit string screen area.
|
// update the preedit string screen area.
|
||||||
update(0, cur_y - d->preedit_lines_*height, viewport()->width(),
|
viewport()->update(0, cur_y - d->preedit_lines_*height, viewport()->width(),
|
||||||
(height + 1) * d->preedit_lines_);
|
(height + 1) * d->preedit_lines_);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Don't forget to accept the event!
|
// Don't forget to accept the event!
|
||||||
e->accept();
|
e->accept();
|
||||||
|
@ -92,10 +92,6 @@ struct GuiWorkArea::Private
|
|||||||
{
|
{
|
||||||
Private(GuiWorkArea *);
|
Private(GuiWorkArea *);
|
||||||
|
|
||||||
/// update the passed area.
|
|
||||||
void update(int x, int y, int w, int h);
|
|
||||||
///
|
|
||||||
void updateScreen();
|
|
||||||
///
|
///
|
||||||
void resizeBufferView();
|
void resizeBufferView();
|
||||||
|
|
||||||
@ -123,34 +119,9 @@ struct GuiWorkArea::Private
|
|||||||
return need_resize_ || p->pixelRatio() != pixel_ratio_;
|
return need_resize_ || p->pixelRatio() != pixel_ratio_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetScreen()
|
|
||||||
{
|
|
||||||
delete screen_;
|
|
||||||
pixel_ratio_ = p->pixelRatio();
|
|
||||||
if (lyxrc.use_qimage) {
|
|
||||||
QImage *x =
|
|
||||||
new QImage(static_cast<int>(pixel_ratio_ * p->viewport()->width()),
|
|
||||||
static_cast<int>(pixel_ratio_ * p->viewport()->height()),
|
|
||||||
QImage::Format_ARGB32_Premultiplied);
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
x->setDevicePixelRatio(pixel_ratio_);
|
|
||||||
#endif
|
|
||||||
screen_ = x;
|
|
||||||
} else {
|
|
||||||
QPixmap *x =
|
|
||||||
new QPixmap(static_cast<int>(pixel_ratio_ * p->viewport()->width()),
|
|
||||||
static_cast<int>(pixel_ratio_ * p->viewport()->height()));
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
x->setDevicePixelRatio(pixel_ratio_);
|
|
||||||
#endif
|
|
||||||
screen_ = x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
///
|
///
|
||||||
GuiWorkArea * p;
|
GuiWorkArea * p;
|
||||||
///
|
///
|
||||||
QPaintDevice * screen_;
|
|
||||||
///
|
|
||||||
BufferView * buffer_view_;
|
BufferView * buffer_view_;
|
||||||
///
|
///
|
||||||
GuiView * lyx_view_;
|
GuiView * lyx_view_;
|
||||||
|
Loading…
Reference in New Issue
Block a user