Search:   Help



LyX documentation


Shared groups



Categories: GSOC
<< | Page list | >>

This page contains information about the Horizontal Scrollbar GSoC project.

Horizontal scrollbar for tables and math


1.  About the project

The LyX Document processor provides users with an excellent UI for creating and editing LaTeX tables and math. One drawback of the current implementation is that when a table or math equation is too wide so as not to fit on the screen, the right-hand edge will "disappear" outside the screen limits. This makes editing wider tables and equations more difficult, and sometimes requires users to decrease the font size in LyX to be able to see the full table/equation on the screen. Something like a horizontal scroll bar is needed, to access the parts of the document beyond the screen limits.

This problem has been existed for a long time. Check the documented ticket from here.

2.  Developers involved in this project

Student participant: Hashini Senaratne

Mentors : Jean-Marc Lasgouttes, Tommaso Cucinotta

3.  Project proposal

Originally proposed idea can be accessed from here.

View the Project proposal to get more details about the proposed design and the schedule.

Proposed Solution

Feature 1:

Feature 1.1: Keyboard based solution

The idea is, when the text cursor goes outside of the visible window, where a too wide inset contains in the same row that the text cursor lies in, the inset gets scrolled horizontally, until the edge of the inset appears on the screen according to the keyboard left and right arrow presses.

Feature 1.2: Mouse UI solution

The idea is, when the mouse pointer reaches the edge of the screen where a too wide inset contains in the same row that the mouse pointer lies in, a UI element appears to indicate that it is scrollable. The inset gets scrolled horizontally, as long as this UI element is pressed until the edge of the inset appears on the screen. Likewise the too wide inset can be scrolled in both right and left directions and it allows editing the inset easily.

Feature 2:

Currently, a half-baked solution has been added for the functionality of the inset; table. This feature can be observed when a too wide table appears on the screen. When a particular cell is selected using the cursor and if there are more columns beyond the screen, the table gets shifted accordingly to allow the hidden parts to appear on the screen. This half-baked solution has to be removed from the source after implementing Feature 1 successfully.

4.  Schedule

This is a rough timeline for the milestones that I have identified.

27th May16th JuneReading and understanding mostly related LyX source and contacting mentors and other resource persons to gather helpful guidelines for the implementation. Completion of background study for Feature 1 with prototype development of major functions and getting feedback from the mentors.
17th June30th JuneActual implementation of a function to slide a too wide inset by a required amount of x value and get feedback from mentors.
1st July14th JulyModify the source in order to move the insets horizontally according to key board events occurred due to presses of left and right keys arrow keys, if a part of the insert is out of the screen. Get the feedback from the mentors.
15th July28th JulyModify the source in order to move the insets when the cursor reaches the edge of the screen, if a part of the insert is out of the screen. Get the feedback from mentors.
29th July2nd AugustMid-term evaluation.
3rd August17th AugustDecide with UI Elements to add at the edges of the screen and set them only to appear when the mouse reaches if only a part of the insert is out of the screen. Set to scroll insets horizontally, when the UI elements are pressed. Get the feedback from the mentors.
17th August25th AugustCompletion of Feature 2 (Remove the half-backed solution for tables) and get the feedback from mentors.
26th August20th SeptemberImplementation of the secondary goal and get feedback from the mentors.
21st September27th SeptemberClean the code. Final Evaluation.
27th SeptemberAfterSubmit the completed source on 27th of September 2013. Maintain and fix bugs related to this new feature in the future.

5.  Progress

5.1  27th May - 16th June

Week 1 (27th May - 2nd June)

  • Discuss with the developers and mentors about the project details. It is agreed to implement the keyboard feature first and then the UI feature later with both local and global scrolling as it seems to have both pros and cons with each solution.

Week 2 (3rd June - 9th June)

  • Experienced more features of LyX by following video screen-casts and self surfing throughout the document processor.
  • Prepared a list of items/insets need to be scrolled horizontally at the end of the project.

Week 3 (10th June - 16th June)

  • Connected to the GSoC repository student list and learned how to create featured branch for the project.
  • Attempted to understand the cursor behaviour using TextMetrics.cpp and Cursor.cpp, but it is still not clear. Need more studying.

5.2  17th June - 30th June

  • 17th - Alter the code in TextMetrics::drawParagraph() to slide the rows. Although wanted to slide row by row; still the whole page slides as a whole. This implementation is a simple test just to confirm the ability to slide rows.
  • 18th - Did more background study on how to slide a row separately and received help from the mentor regarding this.
  • 19th - Modified the test only to slide when the cursor goes out of the screen limits with the use of attributes: cur.targetX() and bv.workWidth(). These give the current location of the scroll pointer in pixels and the maximum width of the current screen respectively.
    • Still the cursor appearance is not settled.
    • The test is pushed to the branch scroll/testing and a directory named "Testing Templates" is also added to keep a set of templates to test the functionality. Keyboard Test 1,
  • 20th - Tested the last commit.
    • Note that the code related to above commit only applicable to Math inset. cur.targetX() is not changing when the cursor moves along tables, labels or images.
    • Note that when we insert or delete any text after sliding, although the text is added, inset comes back to its starting position. But the cursor position does not come back to 0. This is something to do with drawing.
    • Cursor position is now visible but still some problems to be handled. : Keyboard Test 2
  • 21st - Discovered problems related to the final commit. Had to recommit all due to a git conflict while trying to push.
    • When insert or delete (backspace) any text to a slid Math inset, inset slides to the left-most position. But when continuing moving using arrow keys; starts to slide from the correct position.
    • Try to click within the math inset to get the cursor to that position OR try to select a range of text within the math inset; both will return back to the left-most position of the inset.
    • This implementation does not work for the insets; tables, images and labels because cur.targetX() is not changing when the cursor moves along them.
    • Still the per row sliding has not been implemented.
    • Go to the right most cursor position along the Math inset in changesNeeded.lyx document in Testing Templates. Then press left arrow once; again the inset slides to the left-most position. But correctly continue from there.
    • Go to the right-most cursor position along the Math inset in changesNeeded.lyx as above and press the up arrow for once. This is not the correct position where the cursor should go. Sometimes when trying to move left; process terminated unexpectedly by giving the error:
CoordCache.cpp (40): break on pointer: 0x3838240 hint: x size: 3
lassert.cpp (43): ASSERTION false VIOLATED IN CoordCache.cpp:41
Assertion triggered in void lyx::doAssert(const char*, const char*, long int) by failing check "false" in file lassert.cpp:45
Buffer.cpp (1356): /home/hashini/Desktop/GSoC 2013/Phase 1/changesNeeded.lyx.emergency

Aborted (core dumped)

  • Using numerical values (5 & 10) in modified code (in void GuiWorkArea::Private::showCursor() and TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y)) may not be a good approach, as the cursor position may not applicable for different text sizes.
  • 22nd and 23rd - Nothing much improvements. Was thinking about a better approach and seek Jean's help for proceeding.
  • 24th - Mentor suggested a new approach
    • in Cursor object, add two private members
      • current_row_offset_: the value of the offset for the row the cursor is in. The cursor remembers the offset, which means that, when it goes out of the right margin the row will slide, but when going back on the left we could decide not to slide back the row, until it is necessary because we need to go beyond the left margin.
      • current_row_: (a pointer to) the row the cursor was in when applying an offset. If this is not the current row anymore, we shall reset the offset to 0.
    • then in drawParagraph, use a logic like
      • before the main loop, if cursor current_row_ is not equal to cur.textRow(), reset offset to 0 and current_row_ to new row
      • in the loop, when looking at the row that contains the cursor
        • if the cursor is visible with current offset, do nothing
        • if cursor is not visible (on the left or on the right), adjust the offset so that cursor is visible
        • use the newly computed offset to draw the row.
  • 25th - Was studying and experimenting on the information given by the mentor about CursorSlice, DocIterator, CursorData, Cursor (Refer the Notes section)
  • 26th - Wrote a simple cout lines to test the above values. Test 3
  • 27nd - Started the planned work by adding current_row_offset_, current_row_ attributes and public accessing constant methods to each in the Cursor.h and Cursor.cpp files. Set the value for current_row_offset in void Cursor::setTargetX(int x) method.
  • 28th - Had a skype meeting with Jean-Marc and Tommaso and discussed about current problems that I have regarding the project and the future plans. This was a really helpful and an encouraging session.
  • 29th - As proceeds I figured out that only using the offset value, it is impossible to give a correct output in scrolling. That is, without knowing the already slid amount, we cannot take a decision whether to slide the row or not when the cursor is moving. This can vary from time to time.
    • Following are few examples that can take in to account. Consider about an already slid row.
      • We are going to click on a place which is visible in the current screen (may be from right or left from the current cursor) Note that the implementation that we have in mind, will not have the cursor always at the right edge as in my last test.
      • We can start selecting a range of content in a Math inset by clicking at a point and and move the mouse further to left and release the mouse. How are we going to know whether we passed the screen limits or not?
      • Even it can be a situation where the cursor is at a righter part of the content and we are going to re size the screen (actually reduce) such that the cursor tends to disappear from the screen. At such a moment, we need to slide the row such that the cursor appears in the screen.
      • In the current version of LyX; if we closed a document and re-open it, the cursor appears at the same point where we stopped it. Horizontal scrolling also should support this feature.
    • The solution that I am going to propose it to have a attribute which shows the actual position in pixels of the leftmost position (edge) of the current appearing screen, instead of an offset. We can however compute the offset by: (cur.targetX()- bv.workWidth()) in the drawparagraph() method in TextMetrics.cpp. The only problem that I have is how to get this pixel value of the left edge of the screen?
    • The algorithm would be as follows (screen_width= bv.workWidth())
      • if(cur.targetX()>left_edge_Value && cur.targetX()<left_edge_Value+screen_width) then move only the cursor, do not slide row [Selecting an appearing position scenario]
      • if(cur.targetX()<left_edge_Value) then slide row to right and move the cursor to the right edge [Selecting a range of content with the use of mouse scenario/ reduce the size of the screen from left side]
      • if(cur.targetX()>left_edge_Value && cur.targetX()>left_edge_Value+screen_width) then slide the row to left, move the cursor to the left edge (may not want to move the cursor because it is already at the left edge), [Selecting a range of content with the use of mouse scenario/ reduce the size of the screen from right side]
  • 30th - Conflicts were solved. What Jean meant by the term "offset" was the same as the slid amount in pixels. Hopefully above description is a more detailed one and will be really useful for the implementation.

5.3  1st July - 14th July

  • 1st - After several attempts was able to run the project in Eclipse IDE. Now I can have the ability to traverse quickly through the source files wit added facilities.
  • 2nd - 4th - Could not do much work.
  • 5th - Created variables too_wide_row_ and left_edge_ and getter methods in Cursor.cpp and Cursor.h. Getter methods in Cursor.cpp
  • 6th - Created setter methods to assign values from TextMetrics.cpp. Setter methods added to Cursor.cpp
  • 7th and 8th - Added the sliding logic to the TextMatrics.cpp. But not giving the expected functionality. What is expected is scroll as a whole when the cursor goes out of the limits. But here a not related row gets slid accordingly. Still not the cursor position has updated. But before that, have to solve the above mentioned problem. Sliding Mechanism: step 1
  • 9th and 10th - Was finding the reason for the above mentioned problem.
  • 11th - Figured out the issue. That is; in the for loop (in TextMetrics::drawParagraph() method) I have updated the left edge all the time without any condition.
    • (1) Tried to call this cur.setLeftEdge() method somewhere else in order to get that called only once and at the end of drawing a page/ document. When I place this after the for loop of TextMetrics::drawParagraph(); only one paragraph gets slid. So I tried calling it at the end of the TextMetrics::draw(PainterInfo & pi, int x, int y) const method. But there also, only one

paragraph got slid.

  • (2) If the current algorithm is used, when a row gets slide the cursor will be placed exactly at the right edge. Therefore the cursor will not appear to the outside. Proper solution would be sliding by an amount equals to (current cursor position- cursor position if the cursor is at one letter before (to left).)
  • (3) Figured out that there is a different between cur.targetX() and bv.getPos(cur).x_
  • 12th -
    • Gained the help from the mentor for the above mentioned issues.
      • (1) - Try to identify the row that need to be slid and use that condition to update the left_edge
    Revised algorithm
    if current row is the cursor's textRow
    if cursor's getToowideRow != cursor's texRow
    reset left edge to 0
    if cursor is not visible with current LeftEdge
    increase or decrease leftedge so that the cursor is visible
    add cursor's leftedge to inc_x
    • (2) - Try a simpler solution where keep, a 10 pixels of margin. Or, if pixels are not good because of high-resolution screen issues, use a percentage of max_width (like 3%).
    • (3) - Check the notes
    • Implemented the basic sliding functionality in order to slide a single row, according to the decided algorithm. (When checking it please ignore the cursor positions; I have not implemented that part yet. I kept a 10 pixel margin) Works fine for a Math inset, with sliding.
    • What I have to do more;
      • Modify the cursor appearing positions
      • Modify the code to handle selecting a range of text within a row
      • Update the cursor position, when the selected row get changed (moving from a scrolled row to a non-too wide row)
  • 13th - Read development/coding/CodingRulesAndAdvice.lyx and tried to understand the styles followed by LyX developers.
  • 14th - Edited some parts of TextMetrics.cpp to follow the styles recommenced. I committed this attempt a bit later: Tried to format TextMetrics.cpp according to LyX rules

5.4  15th July - 29th July

  • 15th - Mentor reviewed my code relating to single row sliding and figured out a bug in Cursor::textRow when cursor is in a math inset.
    • Problem: Something very weird: when moving in the long formula, the "Math-Formula" title moves, whereas it should not.
    • The fix suggested by Jean-Mark : Fix to Cursor::textRow
  • 16th - Tried to update the text cursor position accordingly: Updated text cursor- Step 1
    • As Richard mentioned earlier; I should have implemented this functionality in BufferView.cpp. But this time I could not able to figure out where to add this code.
    • When we select a different cursor position in a too wide row using the mouse; the row gets slide unexpectedly. Here the row should not slide and only the text cursor should be moved.
    • When we select a range of text using the mouse or using Shift + Arrowkeys the row do not get slides at once. Sliding happens after we take the mouse pointer back to the screen limits or after we releasing the shift key. I think what we need is make the row slide as soon as the selecting goes beyond screen limits.
    • After sliding a row, if we select another text row that is not too wide; that gets shifted by some amount.
  • 17th - Jean-Mark helped me more with code styles used by LyX.
  • 18th - Figured out a bug: when trying to enter a Math inset either from left corner or right corner of it; as soon as we enter the math equation using arrow keys of keyboard, the row gets slid to a wrong position. (eg: if we are entering the Math equation from right corner; the row gets slid to the beginning of the row (right corner))
  • 19th - Was testing the code to find how the above stated bug initiating.
  • 20th - Tried to fix the above and found that this happens because cur_x variable does not get updated as expected. I save bv.getPos(cur).x_ to cur_x. Consider the folowing scenario;
    • If consider about the left corner of Math equation (note that pixel values depend on the screen size I used. But they would be useful to understand the problem);
      • What is happening normally is for each key stroke, this cur_x gets updated once. (If I do not move the mouse pointer)
      • But just after I enter Math (going from left to right) this gives two 10s; which should have been one 13.
      • When I came to the same position (going from right to left) it gives one 13;which is correct.
      • Next when I just got out from the Math (going from right to left) it gives two 10s; which should have been one 10.
      • My algorithm is not working properly only because of the misbehaviour of moving from left to right at this point. (How many times this value get update do not affect the algorithm)
    • If consider about the right corner of the math equation; what is happening is;
      • When I am inside Math at right corner it gives 2510 and when I press right arrow once gives two 2511; which should have been one 2511.
      • Then when I try to get back into Math; it gives two 10s; which should have been one 2510. That is why the whole row gets slid to the left most edge at this moment. But when I proceed from there; the cur_x gives correct values.
    • So it is clear that when the cur_x does not get the correct value, when the cursor just enter the Math inset. (Either from left corner or right corner).
  • 21st - Commit to show the above bug and that the cur_x is not updated accordingly: Demonstrating the sliding bug when entering an Math inset
  • 22nd - Jean-Mark showed that the current implementation is not working well for smaller font sizes. That is because at the left edge we are comparing the cursor position with left edge and try to keep a margin of ( left edge + 10 )
    • Fix for the above bug : Works well at the edges of the screen for all font sizes along a Math inset
    • A new discovery: When the row slid to a wrong position (say when entering from right corner leftedge is set to 10 pix unexpectedly); if I move the mouse pointer in to and out of the document window; without any key pressing position resets to the current position. So we only need to find out what is missing and force it call.
    • cur_x only gives the correct position in pixels just after entering a Math inset; from the next row (next iteration of the for loop in drawParagraph() method.) The line responsible for updating this bv.getPos(cur).x_ for the current text row is "rp.paintText()". When I check bv.getPos(cur).x_ before this line, it gives the old value for the current row, and when I check bv.getPos(cur).x_ value after this line, it gives the new value.
  • 23rd, 24th and 25th - Was trying to find at which point the screen automatically resets the cursor position due to mouse movements. But failed with this attempt. So decided to temporary stop searching about this and concentrate on fixing the other bugs.
  • 26th - Put main implemented milestones to the master.
  • 27th - Tried to reset left edge value to 0 when moving from a too wide row. Bug When running this code, a run-time error occurred; mentioning;
Error: LyX crashed!
SIGSEGV signal caught!
Sorry, you have found a bug in LyX, hope you have not lost any data.
Please read the bug-reporting instructions in 'Help->Introduction' and send us a bug report, if necessary. Thanks!
  • 28th - Tried to find the run-time error occurred, but failed.
  • 29th - Removed the code responsible for the above mentioned run-time error
  • 30th - Mid Term Evaluation was completed

5.5  31st July - 31st August

  • 31st July - Re-factored code to improve quality after following Jean-Marc's guidlines.
  • 1st August - Re-factored code to improve quality after following Jean-Marc's guidlines.
  • 2nd August - Resolved ambiguity in GuiWorkArea
Some additional cleaups:
  • the extra Cursor members are now mutable for simplicity. This can be changed later.
  • There is a new previous_row_ member that is useful to redraw a row that was scrolled but which is not any more.
  • new method Cursor::bottomRow(), that goes together with textRow()
  • various style changes (constify variables, avoid useless declarations, move declarations where they belong...)
  • Some comments updates
  • 22nd August - Studied the current implementations and suggestions made by the mentor
  • 23rd August - Commited the missing wide_image used in changesNeeded.lyx
  • 24th August - Tried drawing twice using rp.paintText();, but that did not overwrite the line. What I ended up with was, duplication content of the same line, where I cannot go through the duplicated content using arrow keys. Also I could not get an output which fixes the current wrong sliding.
    • When using the vertical scroll bar to reach the bottom of the document, it gives a wired behaviour (floating up and down) and it is impossible to reach the bottom using the scroll bar. But it is ok, when using down arrow keys to reach the bottom. Not sure whether this bug appeared due to the code related to this project.
  • 25th August - It seems to be current problems that we are having with selecting a different position of an already slid row, selecting range of text of that kind of row, not responding to END key (slide to right most position) related to a centralized issue. When we press Home key (within a too wide Math equation), truly we can see the text cursor is moving to the front of the line. But when pressed END, text cursor gets disappear. That moves to the end of the line, but we can't see it as the row is not sliding there. But again if you move the mouse pointer over the Math inset, that will automatically slide to the end of the line.
  • 26th August - Again received help from Jean-Mark on debugging methods (run with "-dbg painting", View>Messages), related method for this problem (BufferView::draw)
  • 27th August - Debugged the code from different perspectives and figured out what are the additional methods that are called when mouse is moving over a Math inset.
Some raw data collected as below.
BufferView.cpp (504): Updating scrollbar: height: 10 curr par: 3 default height 28
GuiWorkArea.cpp (473): WorkArea::redraw screen
//just after entering the Math inset
TextMetrics.cpp (2203): main text redraw pit=4 row=0 row_selection=0 full_repaint=1 row_has_changed=1
TextMetrics.cpp (2203): main text redraw pit=4 row=1 row_selection=0 full_repaint=1 row_has_changed=1
//after the moement of mouse over the Math inset
BufferView.cpp (2898):
BufferView.cpp (2915): Found new anchor pit = 0 anchor ypos = -184
BufferView.cpp (2114): Mouse hover detected at: (854, 191)
BufferView.cpp (2843): *** START DRAWING ***
TextMetrics.cpp (2203): main text redraw pit=0 row=1 row_selection=0 full_repaint=1 row_has_changed=0
  • 28th August - Again tried defining two RowPainter s as suggested by mentor. But failed.
  • 29th August, 31st August - Focused on BufferView::draw and its update_strategy
    • First of all I tried draw again after all the cases of the switch statement by calling tm.draw(pi, 0, y); again. This gave an positive outcome. No unexpected sliding happened at that certain point (entering Math from right). But just after entered, unwanted dash (-/ dash/ minus mark) showed between the right edge of the screen. Appearing sign/ part of the letter differs when the screen size is changed (I am not using a maximized screen). So this part of the letter is something is the equation, appearing at the right edge when the row is not slid.
    • Then I removed the added line and called it again just after the drawing method stated in the last case: "FullScreenUpdate". I could get the same observations as I mentioned above. So I doubt whether this is to do with NoScreenUpdate. I thought code under the comment "// and possibly grey out below" is something to do with this (Something like erasing the unwanted painted part). So I simply used a for loop to call twice the whole content under the case : "FullScreenUpdate". I know is this not a good approach. But this solved the problem I was suffering for weeks. Perhaps we can call this only when a sliding occurs. I see that redrawing all the time is not efficient.
    • This automatically fixed the problem we had with the Home and End key presses.
    • But although I believed that this would solve all the other problems, still the problem relating to selecting a different point of an already slid row and selection of a range of text is not completely solved. The selected point is slid to the right edge (But the previous problem what we had with sliding to the leftmost position is solved).

5.6  1st September - 16th September

  • 1st - 2nd September - Was trying to fix the remaining bugs, but failed
  • 3rd - 5th September - Received help from the mentor.
    • Moving code from TextMetrics to BufferView, with 3 important bug fixes:
    • Recompute inset positions before checking row left edge, by painting the row insets with drawing disabled.
Corresponding change is:
+ // Force the recomputation of inset positions
+ bool const drawing = pi.pain.isDrawingEnabled();
+ pi.pain.setDrawingEnabled(false);
+ // No need to care about vertical position.
+ RowPainter rp(pi, bv.buffer().text(), cur.bottom().pit(), row, bidi, 0, 0);
+ rp.paintOnlyInsets();
+ pi.pain.setDrawingEnabled(drawing);
  • Makes sure that BufferView::draw gets involved when Update flags is just FitCursor (see BufferView::processUpdateFlags) This is the part that starts the draw machinery. Related to code from Buffer.cpp: changed(bool update_metrics) const :if (d->wa_) then d->wa_->redrawAll(update_metrics);
What we do is force a redraw, although we know that most of the times Buffer::draw will not do anything.
Corresponding change is:
- // no screen update is needed.
+ // no screen update is needed in principle, but this
+ // could change if cursor row needs scrolling.
d->update_strategy_ = NoScreenUpdate;
+ buffer_.changed(false);
  • Change update strategy when left edge has changed. This allows to redraw the row when no drawing was scheduled. Something similar needs to be done when the row left by the cursor had a non-zero left edge.
Corresponding change is:
+ if (cur.getLeftEdge() != left_edge
+ && strategy == NoScreenUpdate) {
+ ScreenUpdateStrategy const oldstrat = strategy;
+ strategy = SingleParUpdate;
+ LYXERR0("leftEdge: " << cur.getLeftEdge() << " => " << left_edge
+ << ", Update strategy " << oldstrat << " => " << strategy);
+ }

as cur.getLeftEdge() = left_edge.

  • Also, when normally the text cursor is in the Math inset, the strategy that is used is DecorationUpdate (stragegy=3), and when this particular situation occurs that changes to FullScreenUpdate (stragegy=2).
  • 8th - Fix for the unexpected scrolling happened when entering a Math inset.
    • Identified another two bugs...
    1) When moving from the left most position of a row to the above too wide row using left arrow, row does not get slide. (I think I found a fix for this, have to test more)
    2) When selecting rage of text from left to right, we cannot drag and select if the screen is maximized. We can select beyond screen limit if LyX screen is not maximized (have some space between the right edge of original computer screen and LyX scree's right edge). But in our example, cannot select beyond the '{' character. Do not know the reason for this.
  • 9th September - Was finding solutions for the bug: When moving from the left most position of a row to the above too wide row using left arrow, row does not get slide. (I think I found a fix for this, have to test more)
  • 10th September - Suggested commit for the above mentioned bug: Fixed: When moving from the left most position of a lower row to the above too wide
    • This commit seems to solve the other problems:
      • keyboard scrolling feature based on keyboard seems to work with images
      • Also it works with too long labels.
      • Home and End keys also works fine.
  • 11th September - Suggested commit : Fixed selcting cursor positions using mouse in a too wide row
    • Selecting a different position in an already slid row
    • Selecting a range of text in an already slid row
    • Behaviour related to Home and End keys
  • 12th September - Obtain some good information about unit testing that will help to ensure the project's functionality.
  • 13th September - From the above patch a new bug introduced. When moving from the rightmost position of the math inset to the below row, using right arrow, the content of the below text row get scrolled to left.
  • 14th September - Received some help from the mentor regarding the above mentioned bug.
  • 15th September - The pointer to the current row changes within a math inset and this problem challenges further improvements of the implementation.
    • What may happen is that DecorationUpdate redraw is triggerred when moving the mouse. In this case, the rows would be recreated and change value.
    • A way to avoid that would be to remember the position of the start of the row (a cursor slice pointing at the first character of the row, instead of a pointer to a row. This should be stable when the row is redrawn.
  • 16th September - After some temporary modifications to avoid this bug following problems were encountered.
    • When delete some text within a cell using (backspace or delete key) above problem appears. Also, it seems like more columns are creating. But it is actually not. When click on another cell those disappears.
    • When writing on a already wide cell (set using right click > more > settings > table settings > width), text cursor is not appearing at the correct position. This only happens in a scrolled row. So need to update the cursor position accordingly. See the attachment. (I doubt this is a problem due to the half back solution of table scrolling)

5.7  17th September - 23rd September

  • 17th September - The problem with deleting content within a scrolled inset is solved using row.width() variable, still some problems remains regarding to the table inset.
  • 18th September - Was able to figure out the point at which the vertical scrolling problem introduced, in the code history.
    • This problem has remained for a long time as I can see. The first point this introduced was when using, if (&cur.textRow() == &row).
    • What happens is what is doing inside cur.textRow() affects the vertical scrolling.
  • 19th September - Resolve differences with respect to origin/master
  • 20th September - Wrote a complete log for Key-board based scrolling feature, which will sooner go the scroll/master.
  • 21st September - Resolving disturbed functionality of vertical scrolled bar.
  • 22nd September - Wrap up Key board based horizontal scrolling for wide insets

6.  Alterations for the schedule

  • As it seems like there are many areas that are not well documented and some of the variables which are intended to give particular values (like text cursor positions, current row that the cursor lies in) changes unexpectedly, we needed to alter the schedule a lot.
  • So, it was decided to complete the key-board based scrolling feature under this project, and later involve in UI based scrolling feature separation to this project.

7.  Notes

Some valuable notes Jean-Marc explained to me.

7.1  Cursor

CursorSlice indicates the position of the cursor at local level. It contains in particular:

  * idx(): the cell that contains the cursor (for Tabular or math arrays). Always 0 for 'plain' insets
  * pit(): the index of the current paragraph (only for Texted)
  * pos(): the position in the current paragraph (or in the math equation in Mathed).
  * inset(): the inset in which the cursor is.

DocIterator indicated the position of the cursor in the document. It knows about the current buffer (buffer() method) and contains a vector of CursorSlices that describes the nesting of insets up to the point of interest. Note that operator<< has been implemented, so that one can send a DocIterator to a stream to see its value. It is very helpful to understand the cursor layout.

  * when using idx/pit/pos on a DocIterator, one gets the information from the inner slice (this slice can be accessed as top())
  * inMathed() returns true when the cursor is in a math formula
  * inTexted() returns true when the cursor is in text
  * innerTextSlice() returns the deepest slice that is text (useful when one is in a math equation and looks for the enclosing text)

CursorData is a descendent of Dociterator that contains

  * a second DocIterator object, the anchor, that is useful when selecting.
  * some other data not interesting here

This class is used only for undo and contains the Cursor element that are not GUI-related. In LyX 2.0, Cursor was directly deriving from DocIterator

Cursor is a descendant of CursorData that contains interesting display-related information, in particular targetX(), the horizontal position of the cursor in pixels.

  * one interesting method for what you want to do is textRow(), that returns the inner Row object that contains the cursor

7.2  Different between cur.targetX() and bv.getPos(cur).x_

targetX is where you want the cursor to be, not where it is.

First example. Below, `|' stands for the cursor.

  • foo bar foo bar |foo bar
  • foo bar
  • foo bar foo bar foo bar

Imagine you press CursorDown. The situation is now

  • foo bar foo bar foo bar
  • foo bar|
  • foo bar foo bar foo bar

CursorDown again. Situation becomes

  • foo bar foo bar foo bar
  • foo bar
  • foo bar foo bar |foo bar

This is made possible because, although second paragraph is very short, targetX makes us remember where we want to be.

Another situation where this is useful is when using cursor down in the following text

  • foo bar foo |bar foo bar
  • foo bar<labelinset> bar
  • foo bar foo bar foo bar

Again, knowing the targetX will avoid a `drift' of the cursor as you move down the document.

7.3  Bugs To Fix

  • [Fixed] when row is slid and using cursor up/down, the row should reset.
  • [Fixed] when clicking on a row that is scrolled, the pointer goes to the wrong position when entering from either right or left corner of a Math inset.
  • [Fixed] when we select a different cursor position in a too wide row using the mouse; the row gets slide unexpectedly.
  • [Fixed] when in a long math equation, using Home/End does move the cursor to the right position, but the row is not scrolled to show it.
  • [Fixed] when moving from the left most position of a row to the above too wide row using left arrow, row does not get slide. (I think I found a fix for this, have to test more)
  • [Fixed] when using the vertical scroll bar to reach the bottom of the document, it gives a wired behaviour (floating up and down) and it is impossible to reach the bottom using the scroll bar. But it is ok, when using down arrow keys to reach the bottom. Not sure whether this bug appeared due to the code related to this project.
  • when selecting rage of text from left to right, we cannot drag and select if the screen is maximized. We can select beyond screen limit if LyX screen is not maximized (have some space between the right edge of original computer screen and LyX scree's right edge). But in our example, cannot select beyond the '{' character. Do not know the reason for this.

8.  Done

  • How the cursor position is changed via the source: void GuiWorkArea::Private::showCursor() and showCursor(p.x_, p.y_, h, l_shape, isrtl, completable);
  • How to slide a Row: RowPainter rp(pi, *text_, pit, row, bidi, x, y); in void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) const
  • A separate directory for the project resources: Testing Templates

9.  Resources

10.  Discussions

  • sites) Interested in GSOC Project: "Horizontal scrollbar for tables and math" and Some problems regarding the project
  • sites) GSoC : Horizontal scrollbar
  • sites) Row by Row sliding


Edit - History - Print - Recent Changes - All Recent Changes - Search
Page last modified on 2013-09-23 06:39 UTC