2003-12-15 11:36:19 +00:00
|
|
|
// -*- C++ -*-
|
|
|
|
/**
|
2007-04-26 04:41:58 +00:00
|
|
|
* \file CursorSlice.h
|
2003-12-15 11:36:19 +00:00
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
*
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author Lars Gullik Bjønnes
|
2004-01-13 12:28:35 +00:00
|
|
|
* \author Matthias Ettrich
|
|
|
|
* \author John Levon
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author André Pönitz
|
2004-01-13 12:28:35 +00:00
|
|
|
* \author Dekel Tsur
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author Jürgen Vigna
|
2003-12-15 11:36:19 +00:00
|
|
|
*
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef CURSORSLICE_H
|
|
|
|
#define CURSORSLICE_H
|
|
|
|
|
2004-01-13 12:28:35 +00:00
|
|
|
#include "support/types.h"
|
2007-11-01 22:17:22 +00:00
|
|
|
#include "support/strfwd.h"
|
2007-04-29 13:39:47 +00:00
|
|
|
#include "insets/Inset.h"
|
2004-01-13 12:28:35 +00:00
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
namespace lyx {
|
|
|
|
|
2007-04-29 13:39:47 +00:00
|
|
|
class Inset;
|
2007-04-26 16:06:39 +00:00
|
|
|
class MathData;
|
2007-04-29 23:33:02 +00:00
|
|
|
class Text;
|
2004-01-20 14:25:24 +00:00
|
|
|
class Paragraph;
|
2003-12-15 11:36:19 +00:00
|
|
|
|
|
|
|
/// This encapsulates a single slice of a document iterator as used e.g.
|
|
|
|
/// for cursors.
|
|
|
|
|
2015-03-18 20:31:50 +00:00
|
|
|
// After inset unification, the distinction of InsetMath and Inset as well as
|
2007-04-29 23:33:02 +00:00
|
|
|
// that of MathData and Text should vanish. They are conceptually the
|
2003-12-15 11:36:19 +00:00
|
|
|
// same (now...)
|
|
|
|
|
2007-06-09 12:39:46 +00:00
|
|
|
class CursorSlice {
|
2003-12-15 11:36:19 +00:00
|
|
|
public:
|
2010-01-27 18:10:33 +00:00
|
|
|
/// \name Those needs inset_ access.
|
|
|
|
//@{
|
2007-05-25 23:17:24 +00:00
|
|
|
friend class DocIterator;
|
|
|
|
friend class StableDocIterator;
|
2010-01-27 18:10:33 +00:00
|
|
|
//@}
|
2007-05-25 23:17:24 +00:00
|
|
|
|
2003-12-15 11:36:19 +00:00
|
|
|
/// type for cell number in inset
|
|
|
|
typedef size_t idx_type;
|
2004-01-15 17:34:44 +00:00
|
|
|
/// type for row indices
|
|
|
|
typedef size_t row_type;
|
|
|
|
/// type for col indices
|
|
|
|
typedef size_t col_type;
|
2003-12-15 11:36:19 +00:00
|
|
|
|
|
|
|
///
|
|
|
|
CursorSlice();
|
|
|
|
///
|
2007-04-29 13:39:47 +00:00
|
|
|
explicit CursorSlice(Inset &);
|
2003-12-15 11:36:19 +00:00
|
|
|
|
2010-01-27 18:10:33 +00:00
|
|
|
/// \name Comparison operators.
|
2008-02-11 08:03:03 +00:00
|
|
|
//@{
|
|
|
|
friend bool operator==(CursorSlice const &, CursorSlice const &);
|
|
|
|
friend bool operator!=(CursorSlice const &, CursorSlice const &);
|
|
|
|
friend bool operator<(CursorSlice const &, CursorSlice const &);
|
|
|
|
friend bool operator>(CursorSlice const &, CursorSlice const &);
|
|
|
|
friend bool operator<=(CursorSlice const &, CursorSlice const &);
|
|
|
|
//@}
|
|
|
|
|
Keyboard based horizontal scrolling for wide insets
[This commit is the output of the "horizontal scrolling" GSoC 2013
project, by Hashini Senaratne. The code has been cleaned up, some
variables have been renamed and moved from the Cursor class to
BufferView::Private. This is the base from which I (jmarc) will polish
the feature for landing on master.
Below is the original commit log of Hashini, updated to reflect the
changes that have been done.]
This feature also applicable for other insets; graphics and labels.
This implementation is capable of scrolling a single row when reaching
its content which is beyond the screen limits, using left and right
arrow keys.
The attribute 'horiz_scroll_offset_' introduced in the
BufferView::Private class plays a main role in horizontal scrolling of
the wide rows that grow beyond the screen limits. This attribute
represents by how much pixels the current row that the text cursor
lies in should be get scrolled.
The main logic that is responsible for drawing the scrolled rows is
within the BufferView class, BufferView::checkCursorScrollOffset.
* The main logic is called via BufferView::draw.
* What this does is set the horiz_scroll_offset_ attribute in in order to
show the position that the text cursor lies in.
* To make sure that BufferView::draw gets involved when Update flag is
FitCursor, necessary changes are made in BufferView::processUpdateFlags.
Basically what the logic that used to set the horiz_scroll_offset_
does is,
* The row which the text cursor lies in is identified by a
CursorSlice that points to the beginning of the row. This is the
'rowSlice' variable used in BufferView::checkCursorScrollOffset. Acessors
are added to obtain this variable. Here row objects were not used to
identify the current row, because it appears that row objects can
disappear when doing a decoration update for example. This means that
comparing row pointers is not a good idea, because they can change
without notice.
* Stop calculations of horiz_scroll_offset_ variable, if metrics have not been
computed yet. Otherwise the calls to TextMetrics::parMetrics, calls
redoParagraph and may change the row heigths. Therefore vertical scrolling
feature may get disturbed. This is avoided.
* Using BufferView::::setCurrentRowSlice resets horiz_scroll_offset_
when changing cursor row. This is done in order to prevent unwanted
scrolling that happens when changing the selected row using up and
down arrow keys.
* Recompute inset positions before checking scoll offset of the row, by
painting the row insets with drawing disabled. This is done because the
position of insets is computed within the drawing procedure.
* Current x position of the text cursor is compared with the
horiz_scroll_offset_ value and the other variables like row.width(),
bv.workWidth(). Compute the new horiz_scroll_offset_ value in order
to show where the text cursor lies in. The basics conditions that we
check before recomputing it are, if the text cursor lies rightward to
the current right screen boundary, if the text cursor lies leftward
to the current left screen boundary, if the text cursor lies within
screen boundaries but the length of the row is less than the left
boundary of the screen (this happens when we delete some content of
the row using delete key or backspace key).
* Change update strategy when scrooll offset has changed. This allows to
redraw the row when no drawing was scheduled. By doing so, it was
possible to redraw a wide row when moving to the leftmost position of the
wide row, from the leftmost position of the row below, using the left
arrow key.
In TextMetrics::drawParagraph it is checked whether the current row is
what is drawing now. If it is so, the value used to the x value of the row
for drawing is adapted according to BufferView::horizScrollOffset.
The method used to pass boundary() was fixed to get row when cursor was in
a nested inset. This matter is considered in Cursor::textRow and it is
modified accordingly.
GuiWorkArea::Private::showCursor() is modified to show the cursor position
in a scrolled row.
2014-07-26 11:17:28 +00:00
|
|
|
/// return true if the slice has not been initialized
|
|
|
|
bool empty() const { return !inset_; }
|
2004-01-16 10:55:19 +00:00
|
|
|
/// the current inset
|
2007-04-29 13:39:47 +00:00
|
|
|
Inset & inset() const { return *inset_; }
|
2004-01-26 10:13:15 +00:00
|
|
|
/// return the cell this cursor is in
|
2004-03-25 09:16:36 +00:00
|
|
|
idx_type idx() const { return idx_; }
|
2004-01-26 10:13:15 +00:00
|
|
|
/// return the cell this cursor is in
|
2004-03-25 09:16:36 +00:00
|
|
|
idx_type & idx() { return idx_; }
|
2004-01-26 10:13:15 +00:00
|
|
|
/// return the last cell in this inset
|
|
|
|
idx_type lastidx() const { return nargs() - 1; }
|
2004-11-30 01:59:49 +00:00
|
|
|
/// return the offset of the paragraph this cursor is in
|
2004-11-24 21:53:46 +00:00
|
|
|
pit_type pit() const { return pit_; }
|
2004-11-30 01:59:49 +00:00
|
|
|
/// set the offset of the paragraph this cursor is in
|
2004-11-24 21:53:46 +00:00
|
|
|
pit_type & pit() { return pit_; }
|
2007-08-13 13:36:19 +00:00
|
|
|
/// return the last paragraph offset within the ParagraphList
|
2007-06-09 12:39:46 +00:00
|
|
|
pit_type lastpit() const;
|
2004-03-18 16:41:45 +00:00
|
|
|
/// increments the paragraph this cursor is in
|
|
|
|
void incrementPar();
|
2005-06-30 18:02:39 +00:00
|
|
|
/// decrements the paragraph this cursor is in
|
2004-03-18 16:41:45 +00:00
|
|
|
void decrementPar();
|
2004-01-13 12:28:35 +00:00
|
|
|
/// return the position within the paragraph
|
2004-03-25 09:16:36 +00:00
|
|
|
pos_type pos() const { return pos_; }
|
2004-01-15 17:34:44 +00:00
|
|
|
/// return the position within the paragraph
|
2004-03-25 09:16:36 +00:00
|
|
|
pos_type & pos() { return pos_; }
|
2015-03-18 20:31:50 +00:00
|
|
|
/*!
|
|
|
|
* \return the last position within the paragraph.
|
|
|
|
* Note that this is the position behind the last character or inset,
|
|
|
|
* i.e. you cannot dereference it.
|
|
|
|
*/
|
2004-01-15 17:34:44 +00:00
|
|
|
pos_type lastpos() const;
|
2004-01-16 10:55:19 +00:00
|
|
|
/// return the number of embedded cells
|
2005-07-18 11:00:15 +00:00
|
|
|
size_t nargs() const { return inset_->nargs(); }
|
|
|
|
/// return the number of columns (1 in non-grid-like insets)
|
|
|
|
size_t ncols() const { return inset_->ncols(); }
|
|
|
|
/// return the number of rows (1 in non-grid-like insets)
|
|
|
|
size_t nrows() const { return inset_->nrows(); }
|
2005-07-06 07:28:16 +00:00
|
|
|
/*!
|
|
|
|
* \return the grid row of the current cell.
|
|
|
|
* This does only make sense in grid like insets.
|
|
|
|
*/
|
2004-01-15 17:34:44 +00:00
|
|
|
row_type row() const;
|
2005-07-06 07:28:16 +00:00
|
|
|
/*!
|
|
|
|
* \return the grid column of the current cell.
|
|
|
|
* This does only make sense in grid like insets.
|
|
|
|
*/
|
2004-01-15 17:34:44 +00:00
|
|
|
col_type col() const;
|
2004-01-13 12:28:35 +00:00
|
|
|
|
2003-12-15 11:36:19 +00:00
|
|
|
///
|
|
|
|
/// texted specific stuff
|
|
|
|
///
|
2005-07-06 07:28:16 +00:00
|
|
|
/// returns text corresponding to this position
|
2007-08-23 20:55:34 +00:00
|
|
|
Text * text() const { return inset_->getText(idx_); }
|
2005-07-06 07:28:16 +00:00
|
|
|
/// paragraph in this cell
|
2007-08-23 20:55:34 +00:00
|
|
|
Paragraph & paragraph() const;
|
2003-12-15 11:36:19 +00:00
|
|
|
|
|
|
|
///
|
|
|
|
/// mathed specific stuff
|
|
|
|
///
|
2006-09-16 18:11:38 +00:00
|
|
|
/// returns the owning inset if it is a InsetMath, else 0
|
|
|
|
InsetMath * asInsetMath() const { return inset_->asInsetMath(); }
|
2003-12-15 11:36:19 +00:00
|
|
|
/// returns cell corresponding to this position
|
2007-04-26 16:06:39 +00:00
|
|
|
MathData & cell() const;
|
2003-12-15 11:36:19 +00:00
|
|
|
|
2005-07-06 07:28:16 +00:00
|
|
|
/// write some debug information to \p os
|
2003-12-15 11:36:19 +00:00
|
|
|
friend std::ostream & operator<<(std::ostream &, CursorSlice const &);
|
2007-08-13 13:36:19 +00:00
|
|
|
/// move to next position
|
|
|
|
void forwardPos();
|
|
|
|
/// move to previous position
|
|
|
|
void backwardPos();
|
2007-08-23 21:35:40 +00:00
|
|
|
/// move to next cell
|
|
|
|
void forwardIdx();
|
|
|
|
/// move to previous cell
|
|
|
|
void backwardIdx();
|
2014-10-19 18:43:17 +00:00
|
|
|
/// are we at the end of the cell
|
|
|
|
bool at_cell_end() const;
|
|
|
|
/// are we at the start of the cell
|
|
|
|
bool at_cell_begin() const;
|
2007-08-13 13:36:19 +00:00
|
|
|
/// are we at the end of this slice
|
|
|
|
bool at_end() const;
|
|
|
|
/// are we at the start of this slice
|
|
|
|
bool at_begin() const;
|
|
|
|
|
2007-05-25 23:17:24 +00:00
|
|
|
private:
|
|
|
|
|
2004-03-18 16:41:45 +00:00
|
|
|
/// pointer to 'owning' inset. This is some kind of cache.
|
2007-04-29 13:39:47 +00:00
|
|
|
Inset * inset_;
|
2007-05-25 23:17:24 +00:00
|
|
|
|
2005-07-06 07:28:16 +00:00
|
|
|
/*!
|
|
|
|
* Cell index of a position in this inset.
|
|
|
|
* This is the primary cell information also for grid like insets,
|
|
|
|
* although we have the convenience functions row() and col() for
|
2015-03-18 20:31:50 +00:00
|
|
|
* those.
|
|
|
|
* This means that the corresponding idx_ of a cell in a given row
|
|
|
|
* and column changes every time the number of columns or number
|
2005-07-18 11:00:15 +00:00
|
|
|
* of rows changes. Normally the cursor should stay in the same cell,
|
2005-07-06 07:28:16 +00:00
|
|
|
* so these changes should typically be performed like the following:
|
|
|
|
* \code
|
|
|
|
* row_type const r = cur.row();
|
|
|
|
* col_type const c = cur.col();
|
|
|
|
* // change nrows() and/or ncols()
|
|
|
|
* cur.idx = index(r, c);
|
|
|
|
* \endcode
|
|
|
|
*/
|
2003-12-15 11:36:19 +00:00
|
|
|
idx_type idx_;
|
|
|
|
/// paragraph in this cell (used by texted)
|
2004-11-24 21:53:46 +00:00
|
|
|
pit_type pit_;
|
2003-12-15 11:36:19 +00:00
|
|
|
/// position in this cell
|
|
|
|
pos_type pos_;
|
|
|
|
};
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
} // namespace lyx
|
|
|
|
|
2003-12-15 11:36:19 +00:00
|
|
|
#endif
|