}
-void BufferView::update(bool fitcursor, bool forceupdate)
+void BufferView::update(Update::flags flags)
{
- pimpl_->update(fitcursor, forceupdate);
+ pimpl_->update(flags);
}
class Painter;
class ParIterator;
+
+namespace Update {
+ enum flags {
+ FitCursor = 1,
+ Force = 2,
+ SinglePar = 4
+ };
+
+inline flags operator|(flags const f, flags const g)
+{
+ return static_cast<flags>(int(f) | int(g));
+}
+
+inline flags operator&(flags const f, flags const g)
+{
+ return static_cast<flags>(int(f) & int(g));
+}
+
+} // namespace
+
+
/**
* A buffer view encapsulates a view onto a particular
* buffer, and allows access to operate upon it. A view
* position changes. \c forceupdate means to force an update
* in any case.
*/
- void update(bool fitcursor = true, bool forceupdate = true);
+
+ void update(Update::flags flags = Update::FitCursor | Update::Force);
/// move the screen to fit the cursor. Only to be called with
/// good y coordinates (after a bv::metrics)
bool fitCursor();
* dispatch() itself, because that's called recursively.
*/
if (available()) {
+ screen().prepareCursor();
+ cursor_timeout.setTimeout(100);
cursor_timeout.restart();
- screen().showCursor(*bv_);
+ cursor_timeout.setTimeout(400);
}
}
}
-void BufferView::Pimpl::update(bool fitcursor, bool forceupdate)
+void BufferView::Pimpl::update(Update::flags flags)
{
lyxerr << BOOST_CURRENT_FUNCTION
- << "[fitcursor = " << fitcursor << ','
- << " forceupdate = " << forceupdate
+ << "[fitcursor = " << (flags & Update::FitCursor)
+ << ", forceupdate = " << (flags & Update::Force)
+ << ", singlepar = " << (flags & Update::SinglePar)
<< "] buffer: " << buffer_ << endl;
// Check needed to survive LyX startup
CoordCache backup;
std::swap(theCoords, backup);
- // This call disallows cursor blink to call
- // processEvents. It is necessary to prevent screen
- // redraw being called recursively.
- screen().unAllowSync();
// This, together with doneUpdating(), verifies (using
// asserts) that screen redraw is not called from
// within itself.
// First drawing step
ViewMetricsInfo vi = metrics();
+ bool forceupdate(flags & Update::Force);
- if (fitcursor && fitCursor()) {
+ if ((flags & Update::FitCursor) && fitCursor()) {
forceupdate = true;
- vi = metrics();
+ vi = metrics(flags & Update::SinglePar);
}
if (forceupdate) {
// Second drawing step
if (cur.result().dispatched()) {
// Redraw if requested or necessary.
- update(cur.result().update(), cur.result().update());
+ if (cur.result().update())
+ update(Update::FitCursor | Update::Force);
+ else
+ update();
}
// See workAreaKeyPress
}
-ViewMetricsInfo BufferView::Pimpl::metrics()
+ViewMetricsInfo BufferView::Pimpl::metrics(bool singlepar)
{
// Remove old position cache
theCoords.clear();
// Redo paragraphs above cursor if necessary
int y1 = y0;
- while (y1 > 0 && pit1 > 0) {
+ while (!singlepar && y1 > 0 && pit1 > 0) {
y1 -= text->getPar(pit1).ascent();
--pit1;
text->redoParagraph(pit1);
// Redo paragraphs below cursor if necessary
int y2 = y0;
- while (y2 < bv.workHeight() && pit2 < int(npit) - 1) {
+ while (!singlepar && y2 < bv.workHeight() && pit2 < int(npit) - 1) {
y2 += text->getPar(pit2).descent();
++pit2;
text->redoParagraph(pit2);
<< " y2: " << y2
<< endl;
- return ViewMetricsInfo(pit1, pit2, y1, y2);
+ return ViewMetricsInfo(pit1, pit2, y1, y2, singlepar);
}
//
bool fitCursor();
///
- void update(bool fitcursor = false, bool forceupdate = true);
+ void update(Update::flags flags = Update::Force);
///
void newFile(std::string const &, std::string const &, bool);
///
///
int offset_ref_;
///
- ViewMetricsInfo metrics();
+ ViewMetricsInfo metrics(bool singlepar = false);
};
+2005-05-31 Martin Vermeer <martin.vermeer@hut.fi>
+
+ * BufferView.[Ch] (update):
+ * BufferView_pimpl.[Ch] (update, metrics):
+ * dimension.h (operator==):
+ * lyxfunc.C (dispatch):
+ * metricsinfo.h (ViewMetricsInfo):
+ * rowpainter.C (paintText):
+ * lyxtext.h:
+ * text.C (redoParagraph):
+ * text3.C (dispatch): Make LyX only repaint current paragraph in
+ case of character insert --> speedup. Also fix cursor draw
+ artifacts
+
2005-05-31 Jean-Marc Lasgouttes <lasgouttes@lyx.org>
* bufferview_funcs.C (gotoInset): fix the wrap-around code to
int des;
};
+inline
+bool operator==(Dimension const & a, Dimension const & b)
+{
+ return a.wid == b.wid && a.asc == b.asc && a.des ==b.des ;
+}
+
#endif
+2005-05-31 Martin Vermeer <martin.vermeer@hut.fi>
+
+ * screen.[hC]: better fix, processEvents -related screen update
+ bug
+
2005-05-20 Lars Gullik Bjonnes <larsbj@gullik.net>
* Move the gnome subdir to the Attic
LyXScreen::LyXScreen()
- : greyed_out_(true), cursor_visible_(false), sync_allowed_(true)
+ : greyed_out_(true), cursor_visible_(false)
{
// Start loading the pixmap as soon as possible
if (lyxrc.show_banner) {
void LyXScreen::showCursor(BufferView & bv)
{
- // This code is currently meaningful only for the Qt frontend.
- // This is the place (like below in hideCursor) where
- // processEvents is being called, and things like keystrokes and
- // mouse clicks are being handed to the LyX core, once every
- // cursor blink.
- // THERE IS NOT SUPPOSED TO BE ANY OTHER CALL TO processEvents
- // ANYWHERE ELSE.
- // in BufferView::Pimpl::update() and here, the sync_allowed_
- // guard is set/cleared which is used here to prevent recursive
- // calls to screen update. startUpdating() and doneUpdating() in
- // coordcache again contain asserts to detect such recursion.
- if (sync_allowed_)
- lyx_gui::sync_events();
-
if (cursor_visible_)
return;
void LyXScreen::hideCursor()
{
- if (sync_allowed_)
- lyx_gui::sync_events();
-
if (!cursor_visible_)
return;
}
+void LyXScreen::prepareCursor()
+{
+ cursor_visible_ = false;
+}
+
+
void LyXScreen::redraw(BufferView & bv, ViewMetricsInfo const & vi)
{
greyed_out_ = false;
expose(0, 0, workarea().workWidth(), workarea().workHeight());
workarea().getPainter().end();
theCoords.doneUpdating();
- sync_allowed_ = true;
}
/// toggle the cursor's visibility
void toggleCursor(BufferView & bv);
- ///
- void unAllowSync() { sync_allowed_ = false; };
+ /// set cursor_visible_ to false in prep for re-display
+ void prepareCursor();
+
protected:
/// cause the display of the given area of the work area
/// is the cursor currently displayed
bool cursor_visible_;
- ///
- bool sync_allowed_;
};
#endif // SCREEN_H
// Redraw screen unless explicitly told otherwise.
// This also initializes the position cache for all insets
// in (at least partially) visible top-level paragraphs.
- view()->update(true, update);
+ if (update)
+ view()->update(Update::FitCursor | Update::Force);
+ else
+ view()->update(Update::FitCursor);
// if we executed a mutating lfun, mark the buffer as dirty
// FIXME: Why not use flag.enabled() but call getStatus again?
void setFont(LCursor & cur, LyXFont const &, bool toggleall = false);
/// rebreaks the given par
- void redoParagraph(pit_type pit);
+ bool redoParagraph(pit_type pit);
/// returns pos in given par at given x coord
pos_type x2pos(pit_type pit, int row, int x) const;
class ViewMetricsInfo
{
public:
- ViewMetricsInfo(lyx::pit_type p1, lyx::pit_type p2,
- int y1, int y2) : p1(p1), p2(p2), y1(y1), y2(y2) {}
+ ViewMetricsInfo(lyx::pit_type p1, lyx::pit_type p2, int y1, int y2,
+ bool singlepar) : p1(p1), p2(p2), y1(y1), y2(y2),
+ singlepar(singlepar) {}
lyx::pit_type p1;
lyx::pit_type p2;
int y1;
int y2;
+ bool singlepar;
};
// paint one paragraph above and one below
+ // Note MV: this cannot be suppressed even for singlepar.
+ // Try viewing the User Guide Mobius figure
if (vi.p1 > 0) {
text->redoParagraph(vi.p1 - 1);
paintPar(pi, *bv.text(), vi.p1 - 1, 0,
}
-void LyXText::redoParagraph(pit_type const pit)
+bool LyXText::redoParagraph(pit_type const pit)
{
// remove rows of paragraph, keep track of height changes
Paragraph & par = pars_[pit];
dim.asc += par.rows()[0].ascent();
dim.des -= par.rows()[0].ascent();
+
+ bool const same = dim == par.dim();
+
par.dim() = dim;
//lyxerr << "redoParagraph: " << par.rows().size() << " rows\n";
+
+ return !same;
}
{
//we don't call update(true, false) directly to save a metrics call
if (cur.bv().fitCursor())
- cur.bv().update(false, true);
+ cur.bv().update(Update::Force);
}
cur.resetAnchor();
moveCursor(cur, false);
- // real_current_font.number can change so we need to
- // update the minibuffer
- if (old_font != real_current_font)
+ needsUpdate = redoParagraph(cur.pit());
+ if (!needsUpdate) {
+ // update only this paragraph
+ cur.bv().update(Update::SinglePar | Update::Force);
+ }
+
bv->updateScrollbar();
break;
}