Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 163769 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jface/text/source/OverviewRuler.java (-39 / +189 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 39-44 Link Here
39
import org.eclipse.swt.widgets.Composite;
39
import org.eclipse.swt.widgets.Composite;
40
import org.eclipse.swt.widgets.Control;
40
import org.eclipse.swt.widgets.Control;
41
import org.eclipse.swt.widgets.Display;
41
import org.eclipse.swt.widgets.Display;
42
import org.eclipse.swt.widgets.ScrollBar;
42
43
43
import org.eclipse.jface.util.Util;
44
import org.eclipse.jface.util.Util;
44
45
Lines 308-313 Link Here
308
	}
309
	}
309
310
310
	/**
311
	/**
312
	 * Container for cached widget infos.
313
	 * 
314
	 * @since 3.7
315
	 */
316
	static class WidgetInfos {
317
		/**
318
		 * the text widget line count
319
		 */
320
		int maxLines;
321
		/**
322
		 * the height of the vertical scrollbar thumb
323
		 */
324
		int thumbHeight;
325
		/**
326
		 * the visible lines of the text widget
327
		 */
328
		double visibleLines;
329
		/**
330
		 * the invisible lines of the text widget
331
		 */
332
		double invisibleLines;
333
		/**
334
		 * the bounds of {@link OverviewRuler#fCanvas}
335
		 */
336
		Rectangle bounds;
337
		/**
338
		 * the writable area in the text widget (height of all lines in pixels)
339
		 */
340
		int writable;
341
	
342
		/**
343
		 * Initializes the widget infos.
344
		 * 
345
		 * @param textWidget the text widget
346
		 * @param canvas the overview ruler canvas
347
		 */
348
		public WidgetInfos(StyledText textWidget, Canvas canvas) {
349
			maxLines= textWidget.getLineCount();
350
			bounds= canvas.getBounds();
351
			writable= JFaceTextUtil.computeLineHeight(textWidget, 0, maxLines, maxLines);
352
			
353
			ScrollBar verticalBar= textWidget.getVerticalBar();
354
			thumbHeight= verticalBar != null ? Math.max(Math.min(bounds.height, verticalBar.getThumbBounds().height), 0) : 0;
355
			
356
	        int partialTopIndex= JFaceTextUtil.getPartialTopIndex(textWidget);
357
	        int topLineHeight= textWidget.getLineHeight(textWidget.getOffsetAtLine(partialTopIndex));
358
	        int topLinePixel= textWidget.getLinePixel(partialTopIndex);
359
	        double topIndex= partialTopIndex - (double) topLinePixel / topLineHeight;
360
	        
361
	        int partialBottomIndex= JFaceTextUtil.getPartialBottomIndex(textWidget);
362
	        int bottomLineHeight= textWidget.getLineHeight(textWidget.getOffsetAtLine(partialBottomIndex));
363
	        int bottomLinePixel= textWidget.getLinePixel(partialBottomIndex);
364
	        double bottomIndex= partialBottomIndex - ((double) bottomLinePixel - textWidget.getClientArea().height) / bottomLineHeight;
365
			
366
	        visibleLines= bottomIndex - topIndex;
367
	        invisibleLines= maxLines - visibleLines;
368
		}
369
	}
370
371
	private static final boolean DEBUG_DRAW= false;
372
	private static final boolean DEBUG_COMPUTE_Y= false;
373
	private static final boolean DEBUG_TO_DOCUMENT_LINE_NUMBER= false;
374
	
375
	/**
311
	 * <code>true</code> if we're on a Mac, where "new GC(canvas)" is expensive.
376
	 * <code>true</code> if we're on a Mac, where "new GC(canvas)" is expensive.
312
	 * @see <a href="https://bugs.eclipse.org/298936">bug 298936</a>
377
	 * @see <a href="https://bugs.eclipse.org/298936">bug 298936</a>
313
	 * @since 3.6
378
	 * @since 3.6
Lines 647-658 Link Here
647
		else
712
		else
648
			visible= fTextViewer.getVisibleRegion(); // legacy support
713
			visible= fTextViewer.getVisibleRegion(); // legacy support
649
714
650
		int maxLines= textWidget.getLineCount();
715
		WidgetInfos infos= null;
651
		Point size= fCanvas.getSize();
716
		
652
		int writable= JFaceTextUtil.computeLineHeight(textWidget, 0, maxLines, maxLines);
653
		if (size.y > writable)
654
			size.y= Math.max(writable - fHeader.getSize().y, 0);
655
656
		for (Iterator iterator= fAnnotationsSortedByLayer.iterator(); iterator.hasNext();) {
717
		for (Iterator iterator= fAnnotationsSortedByLayer.iterator(); iterator.hasNext();) {
657
			Object annotationType= iterator.next();
718
			Object annotationType= iterator.next();
658
719
Lines 688-713 Link Here
688
							continue;
749
							continue;
689
					}
750
					}
690
					
751
					
752
					if (infos == null) {
753
						infos= new WidgetInfos(textWidget, fCanvas);
754
						r.x= INSET;
755
						r.width= infos.bounds.width - (2 * INSET);
756
					}
691
757
692
					try {
758
					try {
759
						int startOffset= visible != null ? annotationOffset - visible.getOffset() : widgetRegion.getOffset();
760
						int startLine= textWidget.getLineAtOffset(startOffset);
761
						
762
						yy= computeY(startLine, infos);
763
						
693
						if (ANNOTATION_HEIGHT_SCALABLE) {
764
						if (ANNOTATION_HEIGHT_SCALABLE) {
694
							int numbersOfLines= document.getNumberOfLines(annotationOffset, annotationLength);
765
							int numbersOfLines= document.getNumberOfLines(annotationOffset, annotationLength);
695
							// don't count empty trailing lines
766
							// don't count empty trailing lines
696
							IRegion lastLine= document.getLineInformationOfOffset(annotationOffset + annotationLength);
767
							IRegion lastLine= document.getLineInformationOfOffset(annotationOffset + annotationLength);
697
							if (lastLine.getOffset() == annotationOffset + annotationLength) {
768
							if (lastLine.getOffset() == annotationOffset + annotationLength) {
698
								numbersOfLines -= 2;
769
								numbersOfLines -= 2;
699
								hh= (numbersOfLines * size.y) / maxLines + ANNOTATION_HEIGHT;
770
								int yy2= computeY(startLine + numbersOfLines, infos);
700
								if (hh < ANNOTATION_HEIGHT)
771
								hh= Math.max(yy2 - yy, ANNOTATION_HEIGHT);
701
									hh= ANNOTATION_HEIGHT;
702
							} else
772
							} else
703
								hh= ANNOTATION_HEIGHT;
773
								hh= ANNOTATION_HEIGHT;
704
						}
774
						}
705
						fAnnotationHeight= hh;
775
						fAnnotationHeight= hh;
706
776
						
707
						int startOffset= visible != null ? annotationOffset - visible.getOffset() : widgetRegion.getOffset();
708
						int startLine= textWidget.getLineAtOffset(startOffset);
709
						yy= Math.min((startLine * size.y) / maxLines, size.y - hh);
710
711
						if (!areColorsComputed) {
777
						if (!areColorsComputed) {
712
							fill= getFillColor(annotationType, style[t] == FilterIterator.TEMPORARY);
778
							fill= getFillColor(annotationType, style[t] == FilterIterator.TEMPORARY);
713
							stroke= getStrokeColor(annotationType, style[t] == FilterIterator.TEMPORARY);
779
							stroke= getStrokeColor(annotationType, style[t] == FilterIterator.TEMPORARY);
Lines 716-731 Link Here
716
782
717
						if (fill != null) {
783
						if (fill != null) {
718
							gc.setBackground(fill);
784
							gc.setBackground(fill);
719
							gc.fillRectangle(INSET, yy, size.x-(2*INSET), hh);
785
							gc.fillRectangle(INSET, yy, infos.bounds.x-(2*INSET), hh);
720
						}
786
						}
721
787
722
						if (stroke != null) {
788
						if (stroke != null) {
723
							gc.setForeground(stroke);
789
							gc.setForeground(stroke);
724
							r.x= INSET;
725
							r.y= yy;
790
							r.y= yy;
726
							if (yy + hh == size.y)
791
							if (yy + hh == infos.bounds.height)
727
								r.y--;
792
								r.y--;
728
							r.width= size.x - (2 * INSET);
729
							r.height= hh;
793
							r.height= hh;
730
							gc.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance
794
							gc.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance
731
							gc.drawRectangle(r);
795
							gc.drawRectangle(r);
Lines 735-740 Link Here
735
				}
799
				}
736
			}
800
			}
737
		}
801
		}
802
		
803
		if (DEBUG_DRAW) {
804
			// draw debugging guides (boundaries):
805
			if (infos == null)
806
				infos= new WidgetInfos(textWidget, fCanvas);
807
			gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_DARK_MAGENTA));
808
			yy= infos.thumbHeight / 2;
809
			gc.drawLine(0, yy, infos.bounds.x/2, yy);
810
			yy= infos.bounds.height - infos.thumbHeight / 2;
811
			gc.drawLine(0, yy, infos.bounds.x/2, yy);
812
			
813
			gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_BLUE));
814
			yy= 0;
815
			gc.drawLine(0, yy, infos.bounds.x/2, yy);
816
			yy= infos.bounds.height - 1;
817
			gc.drawLine(0, yy, infos.bounds.x/2, yy);
818
		}
819
	}
820
821
	/**
822
	 * Computes and returns the y location of the given startLine.
823
	 * 
824
	 * @param startLine the start line
825
	 * @param infos the cached widget infos
826
	 * @return the vertical position of the given startLine in the overview ruler
827
	 * @since 3.7
828
	 */
829
	private int computeY(int startLine, WidgetInfos infos) {
830
		// this is the inverse of #toLineNumbers(int)
831
		
832
		int yy;
833
		if (infos.bounds.height > infos.writable || infos.invisibleLines <= 0) { // too few lines for relative positions: align annotations with textWidget lines
834
			yy = Math.max(0, (2 * startLine + 1) * infos.writable / (infos.maxLines * 2) - infos.bounds.y);
835
			if (DEBUG_COMPUTE_Y)
836
				System.out.println("static: " + yy); //$NON-NLS-1$
837
			
838
		} else if (startLine + 1 < infos.visibleLines / 2) { // before middle of first page: map to area from 0 to thumbHeight/2
839
			yy= (int) (startLine * infos.thumbHeight / infos.visibleLines); // == startLine * (thumbHeight / 2) / (visibleLines / 2);
840
			if (DEBUG_COMPUTE_Y)
841
				System.out.println("start:  " + yy); //$NON-NLS-1$
842
			
843
		} else if (infos.maxLines - infos.visibleLines / 2 <= startLine) { // after middle of last page: map to area from canvasHeight-1 - thumbHeight/2 to canvasHeight-1
844
			yy= (int) (infos.bounds.height-1 - (double)infos.thumbHeight / 2 + (startLine - (infos.maxLines - infos.visibleLines / 2) + 1) * infos.thumbHeight / infos.visibleLines);
845
			if (DEBUG_COMPUTE_Y)
846
				System.out.println("end:    " + yy); //$NON-NLS-1$
847
			
848
		} else {
849
			yy= (int) ((double)infos.thumbHeight/2 + (startLine + 1 - infos.visibleLines / 2) * (infos.bounds.height - infos.thumbHeight) / infos.invisibleLines);
850
			if (DEBUG_COMPUTE_Y)
851
				System.out.println("middle: " + yy); //$NON-NLS-1$
852
		}
853
		// center of rectangle should be at the calculated position:
854
		yy-= ANNOTATION_HEIGHT / 2;
855
		// cap at start/end:
856
		yy= Math.max(0, Math.min(yy, infos.bounds.height-1 - ANNOTATION_HEIGHT));
857
		return yy;
738
	}
858
	}
739
859
740
	/*
860
	/*
Lines 783-810 Link Here
783
	 * @return the corresponding document lines
903
	 * @return the corresponding document lines
784
	 */
904
	 */
785
	private int[] toLineNumbers(int y_coordinate) {
905
	private int[] toLineNumbers(int y_coordinate) {
786
906
		// this is the inverse of #computeY(int, WidgetInfos)
787
		StyledText textWidget=  fTextViewer.getTextWidget();
907
		
788
		int maxLines= textWidget.getContent().getLineCount();
908
		WidgetInfos infos= new WidgetInfos(fTextViewer.getTextWidget(), fCanvas);
789
909
		
790
		int rulerLength= fCanvas.getSize().y;
910
		if (y_coordinate >= infos.writable || y_coordinate >= infos.bounds.height || y_coordinate < 0)
791
		int writable= JFaceTextUtil.computeLineHeight(textWidget, 0, maxLines, maxLines);
792
793
		if (rulerLength > writable)
794
			rulerLength= Math.max(writable - fHeader.getSize().y, 0);
795
796
		if (y_coordinate >= writable || y_coordinate >= rulerLength)
797
			return new int[] {-1, -1};
911
			return new int[] {-1, -1};
798
912
		
799
		int[] lines= new int[2];
913
		int[] lines= new int[2];
800
914
		
801
		int pixel0= Math.max(y_coordinate - 1, 0);
915
		// the "+ 1" below accounts for the offset of the hot spot in typical mouse cursors
802
		int pixel1= Math.min(rulerLength, y_coordinate + 1);
916
		int pixel0= Math.max(y_coordinate - ANNOTATION_HEIGHT / 2 + 1, 0);
803
		rulerLength= Math.max(rulerLength, 1);
917
		int pixel1= Math.min(infos.bounds.height, y_coordinate + ANNOTATION_HEIGHT / 2 + 1);
804
918
		
805
		lines[0]= (pixel0 * maxLines) / rulerLength;
919
		if (infos.bounds.height > infos.writable || infos.invisibleLines <= 0) { // too few lines for relative positions: align annotations with textWidget lines
806
		lines[1]= (pixel1 * maxLines) / rulerLength;
920
//			yy = Math.max(0, (2 * startLine + 1) * infos.writable / (infos.maxLines * 2) - infos.bounds.y);
807
921
			lines[0]= (int) ((pixel0 + infos.bounds.y) * infos.maxLines / (double)infos.writable);
922
			lines[1]= (int) ((pixel1 + infos.bounds.y) * infos.maxLines / (double)infos.writable);
923
			if (DEBUG_TO_DOCUMENT_LINE_NUMBER)
924
				System.out.println("static y: " + y_coordinate + " => [" + lines[0] + ", " + lines[1] + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
925
			
926
		} else if (y_coordinate < infos.thumbHeight / 2) { // before middle of first page: map to area from 0 to thumbHeight/2
927
//			yy= (int) (startLine * infos.thumbHeight / infos.visibleLines);
928
			lines[0] = (int) (pixel0 * infos.visibleLines / infos.thumbHeight);
929
			lines[1] = (int) (pixel1 * infos.visibleLines / infos.thumbHeight);
930
			if (DEBUG_TO_DOCUMENT_LINE_NUMBER)
931
				System.out.println("start  y: " + y_coordinate + " => [" + lines[0] + ", " + lines[1] + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
932
			
933
		} else if (infos.bounds.height - 1 - infos.thumbHeight / 2 < y_coordinate) { // after middle of last page: map to area from canvasHeight-1 - thumbHeight/2 to canvasHeight-1
934
//			yy= (int) (infos.bounds.height-1 - (double)infos.thumbHeight / 2 + (startLine - (infos.maxLines - infos.visibleLines / 2) + 1) * infos.thumbHeight / infos.visibleLines);
935
			lines[0] = (int) ((pixel0 - (infos.bounds.height-1) + (double)infos.thumbHeight / 2) * infos.visibleLines / infos.thumbHeight - 1 + (infos.maxLines - infos.visibleLines / 2));
936
			lines[1] = (int) ((pixel1 - (infos.bounds.height-1) + (double)infos.thumbHeight / 2) * infos.visibleLines / infos.thumbHeight - 1 + (infos.maxLines - infos.visibleLines / 2));
937
			if (DEBUG_TO_DOCUMENT_LINE_NUMBER)
938
				System.out.println("end    y: " + y_coordinate + " => [" + lines[0] + ", " + lines[1] + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
939
			
940
		} else {
941
//			yy= (int) ((double)infos.thumbHeight/2 + (startLine + 1 - infos.visibleLines / 2) * (infos.bounds.height - infos.thumbHeight) / infos.invisibleLines);
942
			lines[0]= (int) ((pixel0 - (double)infos.thumbHeight/2) * infos.invisibleLines / (infos.bounds.height - infos.thumbHeight) - 1 + infos.visibleLines / 2);
943
			lines[1]= (int) ((pixel1 - (double)infos.thumbHeight/2) * infos.invisibleLines / (infos.bounds.height - infos.thumbHeight) - 1 + infos.visibleLines / 2);
944
			if (DEBUG_TO_DOCUMENT_LINE_NUMBER)
945
				System.out.println("middle y: " + y_coordinate + " => [" + lines[0] + ", " + lines[1] + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
946
		}
947
		
808
		if (fTextViewer instanceof ITextViewerExtension5) {
948
		if (fTextViewer instanceof ITextViewerExtension5) {
809
			ITextViewerExtension5 extension= (ITextViewerExtension5) fTextViewer;
949
			ITextViewerExtension5 extension= (ITextViewerExtension5) fTextViewer;
810
			lines[0]= extension.widgetLine2ModelLine(lines[0]);
950
			lines[0]= extension.widgetLine2ModelLine(lines[0]);
Lines 818-824 Link Here
818
			} catch (BadLocationException x) {
958
			} catch (BadLocationException x) {
819
			}
959
			}
820
		}
960
		}
961
		
962
		if (y_coordinate < ANNOTATION_HEIGHT && y_coordinate < infos.bounds.y)
963
			lines[0]= 0;
964
		
965
		if (lines[0] < 0)
966
			lines[0]= 0;
967
		if (lines[1] > infos.maxLines)
968
			lines[1]= infos.maxLines;
821
969
970
		if (DEBUG_TO_DOCUMENT_LINE_NUMBER)
971
			System.out.println("result: [" + lines[0] + ", " + lines[1] + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
822
		return lines;
972
		return lines;
823
	}
973
	}
824
974
(-)src/org/eclipse/jface/text/source/SourceViewer.java (-1 / +26 lines)
Lines 157-162 Link Here
157
				int bottomOffset= clArea.y + clArea.height - scrollbarHeight;
157
				int bottomOffset= clArea.y + clArea.height - scrollbarHeight;
158
				int[] arrowHeights= getVerticalScrollArrowHeights(textWidget, bottomOffset);
158
				int[] arrowHeights= getVerticalScrollArrowHeights(textWidget, bottomOffset);
159
				
159
				
160
				/*
161
				 * Goal: Center of thumb should align with center of line mark in overview ruler. 
162
				 */
163
				
164
//				//TODO: should move this into the painter in OverviewRuler
165
//				
166
//				ScrollBar verticalBar= textWidget.getVerticalBar();
167
//				double thumbTrackHeight= verticalBar.getThumbTrackBounds().height;
168
//				double thumbHeight= verticalBar.getThumbBounds().height;
169
//				double textLineCount= Math.max(1, textWidget.getLineCount());
170
//				int topIndex= textWidget.getTopIndex();
171
//				Rectangle clientArea= textWidget.getClientArea();
172
//				int bottomIndex= textWidget.getLineIndex(clientArea.y + clientArea.height);
173
//				double visibleLineCount= bottomIndex - topIndex + 1;
174
//				// (thumbHeight-additionalThumbHeight)/thumbTrackHeight == visibleLineCount/textLineCount:
175
//				double additionalThumbHeight= Math.max(0, thumbHeight - visibleLineCount/textLineCount*thumbTrackHeight);
176
//				
177
//				//TODO:
178
////				System.out.println(additionalThumbHeight);
179
////				fOverviewRuler.getControl().setBackground(fOverviewRuler.getControl().getDisplay().getSystemColor(SWT.COLOR_GREEN));
180
//				
181
//				int overviewRulerX= clArea.x + clArea.width - overviewRulerWidth - 1;
182
//				int overviewRulerY= (int)(clArea.y + arrowHeights[0] + additionalThumbHeight/2d);
183
//				int overviewRulerHeight= (int)(clArea.height - arrowHeights[0] - arrowHeights[1] - additionalThumbHeight - scrollbarHeight);
184
//				fOverviewRuler.getControl().setBounds(overviewRulerX, overviewRulerY, overviewRulerWidth, overviewRulerHeight);
185
				
160
				int overviewRulerX= clArea.x + clArea.width - overviewRulerWidth - 1;
186
				int overviewRulerX= clArea.x + clArea.width - overviewRulerWidth - 1;
161
				fOverviewRuler.getControl().setBounds(overviewRulerX, clArea.y + arrowHeights[0], overviewRulerWidth, clArea.height - arrowHeights[0] - arrowHeights[1] - scrollbarHeight);
187
				fOverviewRuler.getControl().setBounds(overviewRulerX, clArea.y + arrowHeights[0], overviewRulerWidth, clArea.height - arrowHeights[0] - arrowHeights[1] - scrollbarHeight);
162
				
188
				
Lines 205-211 Link Here
205
				} finally {
231
				} finally {
206
					textWidget.setSize(originalSize); // also resets scroll bar values
232
					textWidget.setSize(originalSize); // also resets scroll bar values
207
				}
233
				}
208
				return arrowHeights;
209
			}
234
			}
210
			return arrowHeights;
235
			return arrowHeights;
211
		}
236
		}

Return to bug 163769