PageRenderTime 177ms CodeModel.GetById 164ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-5-pre1/org/gjt/sp/jedit/textarea/FirstLine.java

#
Java | 364 lines | 263 code | 50 blank | 51 comment | 54 complexity | df1ad9b4decc804b8d824eeaeec8122d MD5 | raw file
  1/*
  2 * FirstLine.java
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 2005 Slava Pestov
  7 *
  8 * This program is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU General Public License
 10 * as published by the Free Software Foundation; either version 2
 11 * of the License, or any later version.
 12 *
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 * You should have received a copy of the GNU General Public License
 19 * along with this program; if not, write to the Free Software
 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 21 */
 22
 23package org.gjt.sp.jedit.textarea;
 24
 25import org.gjt.sp.jedit.Debug;
 26import org.gjt.sp.util.Log;
 27
 28/**
 29 * This Anchor is the first visible line of the textarea.
 30 *
 31 * @author Slava Pestov
 32 * @version $Id: FirstLine.java 15570 2009-06-25 00:43:57Z ezust $
 33 */
 34class FirstLine extends Anchor
 35{
 36	/** The skew is the scroll count from the beginning of the line. Used with soft wrap. */
 37	int skew;
 38
 39	//{{{ FirstLine constructor
 40	FirstLine(DisplayManager displayManager,
 41		TextArea textArea)
 42	{
 43		super(displayManager,textArea);
 44	} //}}}
 45
 46	//{{{ changed() method
 47	@Override
 48	public void changed()
 49	{
 50		//{{{ Debug code
 51		if(Debug.SCROLL_DEBUG)
 52		{
 53			Log.log(Log.DEBUG,this,"changed() before: "
 54				+ physicalLine + ':' + scrollLine
 55				+ ':' + skew);
 56		} //}}}
 57
 58		ensurePhysicalLineIsVisible();
 59
 60		int screenLines = displayManager
 61			.getScreenLineCount(physicalLine);
 62		if(skew >= screenLines)
 63			skew = screenLines - 1;
 64
 65		//{{{ Debug code
 66		if(Debug.SCROLL_VERIFY)
 67		{
 68			System.err.println("SCROLL_VERIFY");
 69			int verifyScrollLine = 0;
 70
 71			for(int i = 0; i < displayManager.getBuffer()
 72				.getLineCount(); i++)
 73			{
 74				if(!displayManager.isLineVisible(i))
 75					continue;
 76
 77				if(i >= physicalLine)
 78					break;
 79
 80				verifyScrollLine += displayManager
 81					.getScreenLineCount(i);
 82			}
 83
 84			if(verifyScrollLine != scrollLine)
 85			{
 86				Exception ex = new Exception(scrollLine + ":" + verifyScrollLine);
 87				Log.log(Log.ERROR,this,ex);
 88			}
 89		}
 90
 91		if(Debug.SCROLL_DEBUG)
 92		{
 93			Log.log(Log.DEBUG,this,"changed() after: "
 94				+ physicalLine + ':' + scrollLine
 95				+ ':' + skew);
 96		} //}}}
 97	} //}}}
 98
 99	//{{{ reset() method
100	@Override
101	public void reset()
102	{
103		if(Debug.SCROLL_DEBUG)
104			Log.log(Log.DEBUG,this,"reset()");
105
106		int oldPhysicalLine = physicalLine;
107		physicalLine = 0;
108		scrollLine = 0;
109
110		int i = displayManager.getFirstVisibleLine();
111
112		for(;;)
113		{
114			if(i >= oldPhysicalLine)
115				break;
116
117			scrollLine += displayManager.getScreenLineCount(i);
118
119			int nextLine = displayManager.getNextVisibleLine(i);
120			if(nextLine == -1)
121				break;
122			else
123				i = nextLine;
124		}
125
126		physicalLine = i;
127
128		int screenLines = displayManager.getScreenLineCount(physicalLine);
129		if(skew >= screenLines)
130			skew = screenLines - 1;
131
132		textArea.updateScrollBar();
133	} //}}}
134
135	//{{{ physDown() method
136	// scroll down by physical line amount
137	void physDown(int amount, int screenAmount)
138	{
139		if(Debug.SCROLL_DEBUG)
140		{
141			Log.log(Log.DEBUG,this,"physDown() start: "
142				+ physicalLine + ':' + scrollLine);
143		}
144
145		skew = 0;
146
147		if(!displayManager.isLineVisible(physicalLine))
148		{
149			int lastVisibleLine = displayManager.getLastVisibleLine();
150			if(physicalLine > lastVisibleLine)
151				physicalLine = lastVisibleLine;
152			else
153			{
154				int nextPhysicalLine = displayManager.getNextVisibleLine(physicalLine);
155				amount -= nextPhysicalLine - physicalLine;
156				scrollLine += displayManager.getScreenLineCount(physicalLine);
157				physicalLine = nextPhysicalLine;
158			}
159		}
160
161		for(;;)
162		{
163			int nextPhysicalLine = displayManager.getNextVisibleLine(
164				physicalLine);
165			if(nextPhysicalLine == -1)
166				break;
167			else if(nextPhysicalLine > physicalLine + amount)
168				break;
169			else
170			{
171				scrollLine += displayManager.getScreenLineCount(physicalLine);
172				amount -= nextPhysicalLine - physicalLine;
173				physicalLine = nextPhysicalLine;
174			}
175		}
176
177		if(Debug.SCROLL_DEBUG)
178		{
179			Log.log(Log.DEBUG,this,"physDown() end: "
180				+ physicalLine + ':' + scrollLine);
181		}
182
183		callChanged = true;
184
185		// JEditTextArea.scrollTo() needs this to simplify
186		// its code
187		if(screenAmount < 0)
188			scrollUp(-screenAmount);
189		else if(screenAmount > 0)
190			scrollDown(screenAmount);
191	} //}}}
192
193	//{{{ physUp() method
194	// scroll up by physical line amount
195	void physUp(int amount, int screenAmount)
196	{
197		if(Debug.SCROLL_DEBUG)
198		{
199			Log.log(Log.DEBUG,this,"physUp() start: "
200				+ physicalLine + ':' + scrollLine);
201		}
202
203		skew = 0;
204
205		if(!displayManager.isLineVisible(physicalLine))
206		{
207			int firstVisibleLine = displayManager.getFirstVisibleLine();
208			if(physicalLine < firstVisibleLine)
209				physicalLine = firstVisibleLine;
210			else
211			{
212				int prevPhysicalLine = displayManager.getPrevVisibleLine(physicalLine);
213				amount -= physicalLine - prevPhysicalLine;
214			}
215		}
216
217		for(;;)
218		{
219			int prevPhysicalLine = displayManager.getPrevVisibleLine(
220				physicalLine);
221			if(prevPhysicalLine == -1)
222				break;
223			else if(prevPhysicalLine < physicalLine - amount)
224				break;
225			else
226			{
227				amount -= physicalLine - prevPhysicalLine;
228				physicalLine = prevPhysicalLine;
229				scrollLine -= displayManager.getScreenLineCount(
230					prevPhysicalLine);
231			}
232		}
233
234		if(Debug.SCROLL_DEBUG)
235		{
236			Log.log(Log.DEBUG,this,"physUp() end: "
237				+ physicalLine + ':' + scrollLine);
238		}
239
240		callChanged = true;
241
242		// JEditTextArea.scrollTo() needs this to simplify
243		// its code
244		if(screenAmount < 0)
245			scrollUp(-screenAmount);
246		else if(screenAmount > 0)
247			scrollDown(screenAmount);
248	} //}}}
249
250	//{{{ scrollDown() method
251	// scroll down by screen line amount
252	void scrollDown(int amount)
253	{
254		if(Debug.SCROLL_DEBUG)
255			Log.log(Log.DEBUG,this,"scrollDown()");
256
257		ensurePhysicalLineIsVisible();
258
259		amount += skew;
260
261		skew = 0;
262
263		while(amount > 0)
264		{
265			int screenLines = displayManager.getScreenLineCount(physicalLine);
266			if(amount < screenLines)
267			{
268				skew = amount;
269				break;
270			}
271			else
272			{
273				int nextLine = displayManager.getNextVisibleLine(physicalLine);
274				if(nextLine == -1)
275					break;
276				boolean visible = displayManager.isLineVisible(physicalLine);
277				physicalLine = nextLine;
278				if(visible)
279				{
280					amount -= screenLines;
281					scrollLine += screenLines;
282				}
283			}
284		}
285
286		callChanged = true;
287	} //}}}
288
289	//{{{ scrollUp() method
290	// scroll up by screen line amount
291	void scrollUp(int amount)
292	{
293		if(Debug.SCROLL_DEBUG)
294			Log.log(Log.DEBUG,this,"scrollUp() before:" + this);
295
296		ensurePhysicalLineIsVisible();
297
298		if(amount <= skew)
299		{
300			// the amount is less than the skew, so we stay in the same like, just going
301			// upper
302			skew -= amount;
303		}
304		else
305		{
306			// moving to the first screen line of the current physical line
307			amount -= skew;
308			skew = 0;
309
310			while(amount > 0)
311			{
312				int prevLine = displayManager.getPrevVisibleLine(physicalLine);
313				if(prevLine == -1)
314					break;
315				// moving to the previous visible physical line
316				physicalLine = prevLine;
317
318				int screenLines = displayManager.getScreenLineCount(physicalLine);
319				scrollLine -= screenLines;
320				if(amount < screenLines)
321				{
322					skew = screenLines - amount;
323					break;
324				}
325				else
326					amount -= screenLines;
327			}
328		}
329
330		if(Debug.SCROLL_DEBUG)
331			Log.log(Log.DEBUG,this,"scrollUp() after:" + this);
332		callChanged = true;
333	} //}}}
334
335	//{{{ ensurePhysicalLineIsVisible() method
336	void ensurePhysicalLineIsVisible()
337	{
338		if(!displayManager.isLineVisible(physicalLine))
339		{
340			if(physicalLine > displayManager.getLastVisibleLine())
341			{
342				physicalLine = displayManager.getLastVisibleLine();
343				scrollLine = displayManager.getScrollLineCount() - 1;
344			}
345			else if(physicalLine < displayManager.getFirstVisibleLine())
346			{
347				physicalLine = displayManager.getFirstVisibleLine();
348				scrollLine = 0;
349			}
350			else
351			{
352				physicalLine = displayManager.getNextVisibleLine(physicalLine);
353				scrollLine += displayManager.getScreenLineCount(physicalLine);
354			}
355		}
356	} //}}}
357
358	//{{{ toString() method
359	@Override
360	public String toString()
361	{
362		return "FirstLine["+physicalLine+','+scrollLine+','+skew+']';
363	} //}}}
364}