mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-09 18:31:04 +00:00
Give PageDown/Up scrolling a sane behaviour. Does not work with selection yet...
* BufferView: - new scroll(), scrollDown() and scrollUp() method for pixel scrolling. - new LFUN_SCREEN_UP/DOWN handling. * TextMetrics: new helper and access methods. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@20283 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
2499fdf7f5
commit
8d52aa5638
@ -592,6 +592,18 @@ FuncStatus BufferView::getStatus(FuncRequest const & cmd)
|
||||
break;
|
||||
}
|
||||
|
||||
case LFUN_SCREEN_UP:
|
||||
case LFUN_SCREEN_DOWN:
|
||||
flag.enabled(true);
|
||||
break;
|
||||
|
||||
// FIXME: LFUN_SCREEN_DOWN_SELECT should be removed from
|
||||
// everywhere else before this can enabled:
|
||||
case LFUN_SCREEN_UP_SELECT:
|
||||
case LFUN_SCREEN_DOWN_SELECT:
|
||||
flag.enabled(false);
|
||||
break;
|
||||
|
||||
default:
|
||||
flag.enabled(false);
|
||||
}
|
||||
@ -935,6 +947,38 @@ Update::flags BufferView::dispatch(FuncRequest const & cmd)
|
||||
break;
|
||||
}
|
||||
|
||||
case LFUN_SCREEN_UP:
|
||||
case LFUN_SCREEN_DOWN: {
|
||||
Point const p = bv_funcs::getPos(*this, cur, cur.boundary());
|
||||
scroll(cmd.action == LFUN_SCREEN_UP? - height_ : height_);
|
||||
cur.reset(buffer_.inset());
|
||||
text_metrics_[&buffer_.text()].editXY(cur, p.x_, p.y_);
|
||||
//FIXME: what to do with cur.x_target()?
|
||||
finishUndo();
|
||||
// The metrics are already up to date. see scroll()
|
||||
updateFlags = Update::None;
|
||||
break;
|
||||
}
|
||||
|
||||
case LFUN_SCREEN_UP_SELECT:
|
||||
case LFUN_SCREEN_DOWN_SELECT: {
|
||||
cur.selHandle(true);
|
||||
size_t initial_depth = cur.depth();
|
||||
Point const p = bv_funcs::getPos(*this, cur, cur.boundary());
|
||||
scroll(cmd.action == LFUN_SCREEN_UP_SELECT? - height_ : height_);
|
||||
// FIXME: We need to verify if the cursor stayed within an inset...
|
||||
//cur.reset(buffer_.inset());
|
||||
text_metrics_[&buffer_.text()].editXY(cur, p.x_, p.y_);
|
||||
finishUndo();
|
||||
while (cur.depth() > initial_depth) {
|
||||
cur.forwardInset();
|
||||
}
|
||||
// FIXME: we need to do a redraw again because of the selection
|
||||
buffer_.changed();
|
||||
updateFlags = Update::Force | Update::FitCursor;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
updateFlags = Update::None;
|
||||
}
|
||||
@ -1138,20 +1182,60 @@ bool BufferView::workAreaDispatch(FuncRequest const & cmd0)
|
||||
}
|
||||
|
||||
|
||||
void BufferView::scroll(int /*lines*/)
|
||||
void BufferView::scroll(int y)
|
||||
{
|
||||
// Text const * t = buffer_.text();
|
||||
// int const line_height = defaultRowHeight();
|
||||
//
|
||||
// // The new absolute coordinate
|
||||
// int new_top_y = top_y() + lines * line_height;
|
||||
//
|
||||
// // Restrict to a valid value
|
||||
// new_top_y = std::min(t->height() - 4 * line_height, new_top_y);
|
||||
// new_top_y = std::max(0, new_top_y);
|
||||
//
|
||||
// scrollDocView(new_top_y);
|
||||
//
|
||||
if (y > 0)
|
||||
scrollDown(y);
|
||||
else if (y < 0)
|
||||
scrollUp(-y);
|
||||
}
|
||||
|
||||
|
||||
void BufferView::scrollDown(int offset)
|
||||
{
|
||||
Text * text = &buffer_.text();
|
||||
TextMetrics & tm = text_metrics_[text];
|
||||
int ymax = height_ + offset;
|
||||
while (true) {
|
||||
std::pair<pit_type, ParagraphMetrics> const & last = tm.last();
|
||||
int bottom_pos = last.second.position() + last.second.descent();
|
||||
if (last.first == text->paragraphs().size() - 1) {
|
||||
if (bottom_pos <= height_)
|
||||
return;
|
||||
offset = min(offset, bottom_pos - height_);
|
||||
break;
|
||||
}
|
||||
if (bottom_pos > ymax)
|
||||
break;
|
||||
tm.newParMetricsDown();
|
||||
}
|
||||
offset_ref_ += offset;
|
||||
updateMetrics(false);
|
||||
buffer_.changed();
|
||||
}
|
||||
|
||||
|
||||
void BufferView::scrollUp(int offset)
|
||||
{
|
||||
Text * text = &buffer_.text();
|
||||
TextMetrics & tm = text_metrics_[text];
|
||||
int ymin = - offset;
|
||||
while (true) {
|
||||
std::pair<pit_type, ParagraphMetrics> const & first = tm.first();
|
||||
int top_pos = first.second.position() - first.second.ascent();
|
||||
if (first.first == 0) {
|
||||
if (top_pos >= 0)
|
||||
return;
|
||||
offset = min(offset, - top_pos);
|
||||
break;
|
||||
}
|
||||
if (top_pos < ymin)
|
||||
break;
|
||||
tm.newParMetricsUp();
|
||||
}
|
||||
offset_ref_ -= offset;
|
||||
updateMetrics(false);
|
||||
buffer_.changed();
|
||||
}
|
||||
|
||||
|
||||
|
@ -128,8 +128,12 @@ public:
|
||||
|
||||
/// center the document view around the cursor.
|
||||
void center();
|
||||
/// scroll document by the given number of lines of default height.
|
||||
void scroll(int lines);
|
||||
/// scroll down document by the given number of pixels.
|
||||
void scrollDown(int pixels);
|
||||
/// scroll up document by the given number of pixels.
|
||||
void scrollUp(int pixels);
|
||||
/// scroll document by the given number of pixels.
|
||||
void scroll(int pixels);
|
||||
/// Scroll the view by a number of pixels.
|
||||
void scrollDocView(int pixels);
|
||||
/// Set the cursor position based on the scrollbar one.
|
||||
|
@ -440,9 +440,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
|
||||
needsUpdate |= cursorDownParagraph(cur);
|
||||
break;
|
||||
|
||||
case LFUN_SCREEN_UP:
|
||||
case LFUN_SCREEN_UP_SELECT:
|
||||
needsUpdate |= cur.selHandle(cmd.action == LFUN_SCREEN_UP_SELECT);
|
||||
needsUpdate |= cur.selHandle(true);
|
||||
if (cur.pit() == 0 && cur.textRow().pos() == 0)
|
||||
cur.undispatched();
|
||||
else {
|
||||
@ -450,9 +449,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
|
||||
}
|
||||
break;
|
||||
|
||||
case LFUN_SCREEN_DOWN:
|
||||
case LFUN_SCREEN_DOWN_SELECT:
|
||||
needsUpdate |= cur.selHandle(cmd.action == LFUN_SCREEN_DOWN_SELECT);
|
||||
needsUpdate |= cur.selHandle(true);
|
||||
if (cur.pit() == cur.lastpit()
|
||||
&& cur.textRow().endpos() == cur.lastpos())
|
||||
cur.undispatched();
|
||||
@ -1853,8 +1851,6 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
|
||||
case LFUN_WORD_SELECT:
|
||||
case LFUN_PARAGRAPH_UP:
|
||||
case LFUN_PARAGRAPH_DOWN:
|
||||
case LFUN_SCREEN_UP:
|
||||
case LFUN_SCREEN_DOWN:
|
||||
case LFUN_LINE_BEGIN:
|
||||
case LFUN_LINE_END:
|
||||
case LFUN_BREAK_LINE:
|
||||
|
@ -139,6 +139,21 @@ ParagraphMetrics const & TextMetrics::parMetrics(pit_type pit) const
|
||||
}
|
||||
|
||||
|
||||
|
||||
pair<pit_type, ParagraphMetrics> const & TextMetrics::first() const
|
||||
{
|
||||
pair<pit_type, ParagraphMetrics> const & pm = *par_metrics_.begin();
|
||||
return pm;
|
||||
}
|
||||
|
||||
|
||||
pair<pit_type, ParagraphMetrics> const & TextMetrics::last() const
|
||||
{
|
||||
pair<pit_type, ParagraphMetrics> const & pm = *par_metrics_.rbegin();
|
||||
return pm;
|
||||
}
|
||||
|
||||
|
||||
ParagraphMetrics & TextMetrics::parMetrics(pit_type pit,
|
||||
bool redo)
|
||||
{
|
||||
@ -1153,6 +1168,33 @@ pos_type TextMetrics::x2pos(pit_type pit, int row, int x) const
|
||||
}
|
||||
|
||||
|
||||
void TextMetrics::newParMetricsDown()
|
||||
{
|
||||
pair<pit_type, ParagraphMetrics> const & last = *par_metrics_.rbegin();
|
||||
pit_type const pit = last.first + 1;
|
||||
if (pit == text_->paragraphs().size())
|
||||
return;
|
||||
|
||||
// do it and update its position.
|
||||
redoParagraph(pit);
|
||||
par_metrics_[pit].setPosition(last.second.position()
|
||||
+ last.second.descent());
|
||||
}
|
||||
|
||||
|
||||
void TextMetrics::newParMetricsUp()
|
||||
{
|
||||
pair<pit_type, ParagraphMetrics> const & first = *par_metrics_.begin();
|
||||
if (first.first == 0)
|
||||
return;
|
||||
|
||||
pit_type const pit = first.first - 1;
|
||||
// do it and update its position.
|
||||
redoParagraph(pit);
|
||||
par_metrics_[pit].setPosition(first.second.position()
|
||||
- first.second.ascent());
|
||||
}
|
||||
|
||||
// y is screen coordinate
|
||||
pit_type TextMetrics::getPitNearY(int y)
|
||||
{
|
||||
|
@ -48,6 +48,11 @@ public:
|
||||
bool has(pit_type pit) const;
|
||||
///
|
||||
ParagraphMetrics const & parMetrics(pit_type) const;
|
||||
///
|
||||
std::pair<pit_type, ParagraphMetrics> const & first() const;
|
||||
///
|
||||
std::pair<pit_type, ParagraphMetrics> const & last() const;
|
||||
|
||||
///
|
||||
int parPosition(pit_type pit) const;
|
||||
|
||||
@ -57,9 +62,15 @@ public:
|
||||
Point const & origin() const { return origin_; }
|
||||
|
||||
|
||||
|
||||
/// compute text metrics.
|
||||
bool metrics(MetricsInfo & mi, Dimension & dim);
|
||||
|
||||
///
|
||||
void newParMetricsDown();
|
||||
///
|
||||
void newParMetricsUp();
|
||||
|
||||
/// Gets the fully instantiated font at a given position in a paragraph
|
||||
/// Basically the same routine as Paragraph::getFont() in Paragraph.cpp.
|
||||
/// The difference is that this one is used for displaying, and thus we
|
||||
|
@ -643,13 +643,11 @@ goto_char_backwards:
|
||||
break;
|
||||
|
||||
case LFUN_SCREEN_UP_SELECT:
|
||||
case LFUN_SCREEN_UP:
|
||||
cmd = FuncRequest(LFUN_FINISHED_LEFT);
|
||||
cur.undispatched();
|
||||
break;
|
||||
|
||||
case LFUN_SCREEN_DOWN_SELECT:
|
||||
case LFUN_SCREEN_DOWN:
|
||||
cmd = FuncRequest(LFUN_FINISHED_RIGHT);
|
||||
cur.undispatched();
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user