- rework update handling, make cursor movement faster,

fixing lots of navigation problems.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@15470 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Asger Ottar Alstrup 2006-10-22 11:46:36 +00:00
parent fa299aa246
commit 37e164c6f9
11 changed files with 90 additions and 88 deletions

View File

@ -18,7 +18,7 @@
#include "coordcache.h"
#include "cursor.h"
#include "metricsinfo.h"
#include "UpdateFlags.h"
#include "support/types.h"
#include <boost/utility.hpp>
@ -41,26 +41,6 @@ class LyXText;
class ParIterator;
class ViewMetricsInfo;
namespace Update {
enum flags {
FitCursor = 1,
Force = 2,
SinglePar = 4,
MultiParSel = 8
};
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
/// Scrollbar Parameters
struct ScrollbarParameters
{

28
src/UpdateFlags.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef UPDATE_FLAGS_H
#define UPDATE_FLAGS_H
namespace lyx {
namespace Update {
enum flags {
None = 0,
FitCursor = 1,
Force = 2,
SinglePar = 4,
MultiParSel = 8
};
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
} // namespace lyx
#endif

View File

@ -285,7 +285,7 @@ void LCursor::dispatch(FuncRequest const & cmd0)
// The common case is 'LFUN handled, need update', so make the
// LFUN handler's life easier by assuming this as default value.
// The handler can reset the update and val flags if necessary.
disp_.update(true);
disp_.update(Update::FitCursor | Update::Force);
disp_.dispatched(true);
inset().dispatch(*this, cmd);
if (disp_.dispatched())
@ -296,7 +296,7 @@ void LCursor::dispatch(FuncRequest const & cmd0)
if (!disp_.dispatched()) {
lyxerr[Debug::DEBUG] << "RESTORING OLD CURSOR!" << endl;
operator=(safe);
disp_.update(false);
disp_.update(Update::None);
disp_.dispatched(false);
}
}
@ -527,14 +527,15 @@ void LCursor::info(odocstream & os) const
}
void LCursor::selHandle(bool sel)
bool LCursor::selHandle(bool sel)
{
//lyxerr << "LCursor::selHandle" << endl;
if (sel == selection())
return;
return false;
resetAnchor();
selection() = sel;
return true;
}
@ -1212,15 +1213,15 @@ void LCursor::dispatched()
}
void LCursor::needsUpdate()
void LCursor::updateFlags(Update::flags f)
{
disp_.update(true);
disp_.update(f);
}
void LCursor::noUpdate()
{
disp_.update(false);
disp_.update(Update::None);
}

View File

@ -86,7 +86,7 @@ public:
/// access start of selection
DocIterator selectionEnd() const;
///
void selHandle(bool selecting);
bool selHandle(bool selecting);
//
docstring selectionAsString(bool label) const;
///
@ -158,8 +158,8 @@ public:
void undispatched();
/// the event was already dispatched
void dispatched();
/// call update() when done
void needsUpdate();
/// Set which update should be done
void updateFlags(Update::flags f);
/**
* don't call update() when done
*

View File

@ -13,28 +13,30 @@
#ifndef DISPATCH_RESULT_H
#define DISPATCH_RESULT_H
#include "UpdateFlags.h"
namespace lyx {
/// Maybe this can go entirely
class DispatchResult {
public:
///
DispatchResult() : dispatched_(false), update_(false) {}
DispatchResult() : dispatched_(false), update_(Update::None) {}
///
DispatchResult(bool disp, bool upd) : dispatched_(disp), update_(upd) {}
DispatchResult(bool disp, Update::flags f) : dispatched_(disp), update_(f) {}
//
bool dispatched() const { return dispatched_; }
///
void dispatched(bool disp) { dispatched_ = disp; }
///
bool update() const { return update_; }
Update::flags update() const { return update_; }
///
void update(bool up) { update_ = up; }
void update(Update::flags f) { update_ = f; }
private:
/// was the event fully dispatched?
bool dispatched_;
/// do we need to redraw the screen afterwards?
bool update_;
Update::flags update_;
};

View File

@ -140,6 +140,7 @@ void ControlDocument::dispatchParams()
"assign branch"));
}
// update the bufferview
// If we used an LFUN, we would not need that
kernel().bufferview()->update();
}

View File

@ -306,6 +306,7 @@ void ControlSpellchecker::replace(string const & replacement)
BufferView & bufferview = *kernel().bufferview();
cap::replaceSelectionWithString(bufferview.cursor(), replacement, true);
kernel().buffer().markDirty();
// If we used an LFUN, we would not need that
bufferview.update();
// fix up the count
--count_;

View File

@ -125,7 +125,7 @@ InsetBase::Code InsetBase::translate(std::string const & name)
void InsetBase::dispatch(LCursor & cur, FuncRequest & cmd)
{
cur.needsUpdate();
cur.updateFlags(Update::Force | Update::FitCursor);
cur.dispatched();
doDispatch(cur, cmd);
}

View File

@ -1251,7 +1251,7 @@ void InsetTabular::resetPos(LCursor & cur) const
scx_ = 0;
}
cur.needsUpdate();
cur.updateFlags(Update::Force | Update::FitCursor);
InsetTabularMailer(*this).updateDialog(&bv);
}

View File

@ -729,9 +729,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
// redraw the screen at the end (first of the two drawing steps).
//This is done unless explicitely requested otherwise
bool update = true;
// also do the second redrawing step. Only done if requested.
bool updateforce = false;
Update::flags updateFlags = Update::FitCursor;
FuncStatus const flag = getStatus(cmd);
if (!flag.enabled()) {
@ -819,12 +817,12 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
lyx_view_->message(str + _(" done."));
} else
writeAs(lyx_view_->buffer());
update = false;
updateFlags = Update::None;
break;
case LFUN_BUFFER_WRITE_AS:
writeAs(lyx_view_->buffer(), argument);
update = false;
updateFlags = Update::None;
break;
case LFUN_BUFFER_RELOAD: {
@ -1425,7 +1423,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
}
// ideally, the update flag should be set by the insets,
// but this is not possible currently
updateforce = true;
updateFlags = Update::Force | Update::FitCursor;
break;
}
@ -1449,7 +1447,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
it->dispatch(tmpcur, fr);
}
}
updateforce = true;
updateFlags = Update::Force | Update::FitCursor;
break;
}
@ -1558,7 +1556,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
buffer->errors("Class Switch");
updateLabels(*buffer);
updateforce = true;
updateFlags = Update::Force | Update::FitCursor;
break;
}
@ -1589,10 +1587,10 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
default: {
view()->cursor().dispatch(cmd);
update = false;
updateforce |= view()->cursor().result().update();
updateFlags = view()->cursor().result().update();
if (!view()->cursor().result().dispatched())
updateforce |= view()->dispatch(cmd);
if (view()->dispatch(cmd))
updateFlags = Update::Force | Update::FitCursor;
break;
}
}
@ -1601,13 +1599,16 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
// Redraw screen unless explicitly told otherwise.
// This also initializes the position cache for all insets
// in (at least partially) visible top-level paragraphs.
if (updateforce)
view()->update(Update::FitCursor | Update::Force);
else if (update)
view()->update(Update::FitCursor);
bool needSecondUpdate = false;
if (updateFlags != Update::None)
view()->update(updateFlags);
else
needSecondUpdate = view()->fitCursor();
view()->buffer()->changed();
lyx_view_->updateStatusBar();
if (needSecondUpdate || updateFlags != Update::None) {
view()->buffer()->changed();
lyx_view_->updateStatusBar();
}
// if we executed a mutating lfun, mark the buffer as dirty
if (flag.enabled()

View File

@ -283,14 +283,6 @@ bool doInsertInset(LCursor & cur, LyXText * text,
}
void update(LCursor & cur)
{
//we don't call update(true, false) directly to save a metrics call
if (cur.bv().fitCursor())
cur.bv().update(Update::Force);
}
} // anon namespace
@ -404,7 +396,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_BUFFER_BEGIN:
case LFUN_BUFFER_BEGIN_SELECT:
cur.selHandle(cmd.action == LFUN_BUFFER_BEGIN_SELECT);
needsUpdate |= cur.selHandle(cmd.action == LFUN_BUFFER_BEGIN_SELECT);
if (cur.depth() == 1) {
needsUpdate |= cursorTop(cur);
} else {
@ -414,7 +406,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_BUFFER_END:
case LFUN_BUFFER_END_SELECT:
cur.selHandle(cmd.action == LFUN_BUFFER_END_SELECT);
needsUpdate |= cur.selHandle(cmd.action == LFUN_BUFFER_END_SELECT);
if (cur.depth() == 1) {
needsUpdate |= cursorBottom(cur);
} else {
@ -426,7 +418,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_CHAR_FORWARD_SELECT:
//lyxerr << BOOST_CURRENT_FUNCTION
// << " LFUN_CHAR_FORWARD[SEL]:\n" << cur << endl;
cur.selHandle(cmd.action == LFUN_CHAR_FORWARD_SELECT);
needsUpdate |= cur.selHandle(cmd.action == LFUN_CHAR_FORWARD_SELECT);
if (isRTL(cur.paragraph()))
needsUpdate |= cursorLeft(cur);
else
@ -442,7 +434,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_CHAR_BACKWARD:
case LFUN_CHAR_BACKWARD_SELECT:
//lyxerr << "handle LFUN_CHAR_BACKWARD[_SELECT]:\n" << cur << endl;
cur.selHandle(cmd.action == LFUN_CHAR_BACKWARD_SELECT);
needsUpdate |= cur.selHandle(cmd.action == LFUN_CHAR_BACKWARD_SELECT);
if (isRTL(cur.paragraph()))
needsUpdate |= cursorRight(cur);
else
@ -457,11 +449,11 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_UP:
case LFUN_UP_SELECT:
update(cur);
//lyxerr << "handle LFUN_UP[SEL]:\n" << cur << endl;
cur.selHandle(cmd.action == LFUN_UP_SELECT);
needsUpdate |= cur.selHandle(cmd.action == LFUN_UP_SELECT);
needsUpdate |= cursorUp(cur);
if (!needsUpdate && oldTopSlice == cur.top()
&& cur.boundary() == oldBoundary) {
cur.undispatched();
@ -471,10 +463,10 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_DOWN:
case LFUN_DOWN_SELECT:
update(cur);
//lyxerr << "handle LFUN_DOWN[SEL]:\n" << cur << endl;
cur.selHandle(cmd.action == LFUN_DOWN_SELECT);
needsUpdate |= cur.selHandle(cmd.action == LFUN_DOWN_SELECT);
needsUpdate |= cursorDown(cur);
if (!needsUpdate && oldTopSlice == cur.top() &&
cur.boundary() == oldBoundary)
{
@ -485,20 +477,19 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_PARAGRAPH_UP:
case LFUN_PARAGRAPH_UP_SELECT:
cur.selHandle(cmd.action == LFUN_PARAGRAPH_UP_SELECT);
needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_UP_SELECT);
needsUpdate |= cursorUpParagraph(cur);
break;
case LFUN_PARAGRAPH_DOWN:
case LFUN_PARAGRAPH_DOWN_SELECT:
cur.selHandle(cmd.action == LFUN_PARAGRAPH_DOWN_SELECT);
needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_DOWN_SELECT);
needsUpdate |= cursorDownParagraph(cur);
break;
case LFUN_SCREEN_UP:
case LFUN_SCREEN_UP_SELECT:
update(cur);
cur.selHandle(cmd.action == LFUN_SCREEN_UP_SELECT);
needsUpdate |= cur.selHandle(cmd.action == LFUN_SCREEN_UP_SELECT);
if (cur.pit() == 0 && cur.textRow().pos() == 0) {
cur.undispatched();
cmd = FuncRequest(LFUN_FINISHED_UP);
@ -509,8 +500,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_SCREEN_DOWN:
case LFUN_SCREEN_DOWN_SELECT:
update(cur);
cur.selHandle(cmd.action == LFUN_SCREEN_DOWN_SELECT);
needsUpdate |= cur.selHandle(cmd.action == LFUN_SCREEN_DOWN_SELECT);
if (cur.pit() == cur.lastpit()
&& cur.textRow().endpos() == cur.lastpos()) {
cur.undispatched();
@ -522,21 +512,19 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_LINE_BEGIN:
case LFUN_LINE_BEGIN_SELECT:
update(cur);
cur.selHandle(cmd.action == LFUN_LINE_BEGIN_SELECT);
needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_BEGIN_SELECT);
needsUpdate |= cursorHome(cur);
break;
case LFUN_LINE_END:
case LFUN_LINE_END_SELECT:
update(cur);
cur.selHandle(cmd.action == LFUN_LINE_END_SELECT);
needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_END_SELECT);
needsUpdate |= cursorEnd(cur);
break;
case LFUN_WORD_FORWARD:
case LFUN_WORD_FORWARD_SELECT:
cur.selHandle(cmd.action == LFUN_WORD_FORWARD_SELECT);
needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_FORWARD_SELECT);
if (isRTL(cur.paragraph()))
needsUpdate |= cursorLeftOneWord(cur);
else
@ -545,7 +533,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_WORD_BACKWARD:
case LFUN_WORD_BACKWARD_SELECT:
cur.selHandle(cmd.action == LFUN_WORD_BACKWARD_SELECT);
needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_BACKWARD_SELECT);
if (isRTL(cur.paragraph()))
needsUpdate |= cursorRightOneWord(cur);
else
@ -1473,15 +1461,15 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
break;
}
needsUpdate |= (cur.pos() != cur.lastpos()) && cur.selection();
if (singleParUpdate)
// Inserting characters does not change par height
if (cur.bottom().paragraph().dim().height()
== olddim.height()) {
// if so, update _only_ this paragraph
cur.bv().update(Update::SinglePar |
Update::FitCursor |
Update::MultiParSel);
cur.noUpdate();
cur.updateFlags(Update::SinglePar |
Update::FitCursor |
Update::MultiParSel);
return;
} else
needsUpdate = true;
@ -1492,7 +1480,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
&& !cur.selection())
cur.noUpdate();
else
cur.needsUpdate();
cur.updateFlags(Update::Force | Update::FitCursor);
}