📄 displaymanager.java
字号:
if(textArea.getDisplayManager() == this) { try { if(firstLine.callReset) firstLine.reset(); else if(firstLine.callChanged) firstLine.changed(); if(scrollLineCount.callReset) scrollLineCount.reset(); else if(scrollLineCount.callChanged) scrollLineCount.changed(); } finally { firstLine.callReset = firstLine.callChanged = false; scrollLineCount.callReset = scrollLineCount.callChanged = false; } } } //}}} //}}} //{{{ Private members private boolean initialized; private boolean inUse; private Buffer buffer; private LineManager lineMgr; private JEditTextArea textArea; private BufferChangeHandler bufferChangeHandler; /** * The fold visibility map. * * All lines from fvm[2*n] to fvm[2*n+1]-1 inclusive are visible. * All lines from position fvm[2*n+1] to fvm[2*n+2]-1 inclusive are * invisible. * * Examples: * --------- * All lines visible: { 0, buffer.getLineCount() } * Narrow from a to b: { a, b + 1 } * Collapsed fold from a to b: { 0, a + 1, b, buffer.getLineCount() } * * Note: length is always even. */ private int[] fvm; private int fvmcount; private int lastfvmget = -1; //{{{ DisplayManager constructor private DisplayManager(Buffer buffer, JEditTextArea textArea) { this.buffer = buffer; this.lineMgr = buffer._getLineManager(); this.textArea = textArea; scrollLineCount = new ScrollLineCount(); firstLine = new FirstLine(); bufferChangeHandler = new BufferChangeHandler(); // this listener priority thing is a bad hack... buffer.addBufferChangeListener(bufferChangeHandler, Buffer.HIGH_PRIORITY); } //}}} //{{{ dispose() method private void dispose() { buffer.removeBufferChangeListener(bufferChangeHandler); } //}}} //{{{ fvmreset() method private void fvmreset() { lastfvmget = -1; fvmcount = 2; fvm[0] = 0; fvm[1] = buffer.getLineCount(); } //}}} //{{{ fvmget() method /** * Returns the fold visibility map index for the given line. */ private int fvmget(int line) { scanCount++; if(line < fvm[0]) return -1; if(line >= fvm[fvmcount - 1]) return fvmcount - 1; if(lastfvmget != -1) { if(line >= fvm[lastfvmget]) { if(lastfvmget == fvmcount - 1 || line < fvm[lastfvmget + 1]) { return lastfvmget; } } } int start = 0; int end = fvmcount - 1;loop: for(;;) { scannedLines++; switch(end - start) { case 0: lastfvmget = start; break loop; case 1: int value = fvm[end]; if(value <= line) lastfvmget = end; else lastfvmget = start; break loop; default: int pivot = (end + start) / 2; value = fvm[pivot]; if(value == line) { lastfvmget = pivot; break loop; } else if(value < line) start = pivot; else end = pivot - 1; break; } } return lastfvmget; } //}}} //{{{ fvmput() method /** * Replaces from <code>start</code> to <code>end-1</code> inclusive with * <code>put</code>. Update <code>fvmcount</code>. */ private void fvmput(int start, int end, int[] put) { if(Debug.FOLD_VIS_DEBUG) { StringBuffer buf = new StringBuffer("{"); if(put != null) { for(int i = 0; i < put.length; i++) { if(i != 0) buf.append(','); buf.append(put[i]); } } buf.append("}"); Log.log(Log.DEBUG,this,"fvmput(" + start + "," + end + "," + buf + ")"); } int putl = (put == null ? 0 : put.length); int delta = putl - (end - start); if(fvmcount + delta > fvm.length) { int[] newfvm = new int[fvm.length * 2 + 1]; System.arraycopy(fvm,0,newfvm,0,fvmcount); fvm = newfvm; } if(delta != 0) { System.arraycopy(fvm,end,fvm,start + putl, fvmcount - end); } if(putl != 0) { System.arraycopy(put,0,fvm,start,put.length); } fvmcount += delta; fvmdump(); if(fvmcount == 0) throw new InternalError(); } //}}} //{{{ fvmput2() method /** * Merge previous and next entry if necessary. */ private void fvmput2(int starti, int endi, int start, int end) { if(Debug.FOLD_VIS_DEBUG) { Log.log(Log.DEBUG,this,"*fvmput2(" + starti + "," + endi + "," + start + "," + end + ")"); } if(starti != -1 && fvm[starti] == start) { if(endi <= fvmcount - 2 && fvm[endi + 1] == end + 1) { fvmput(starti,endi + 2,null); } else { fvmput(starti,endi + 1, new int[] { end + 1 }); } } else { if(endi != fvmcount - 1 && fvm[endi + 1] == end + 1) { fvmput(starti + 1,endi + 2, new int[] { start }); } else { fvmput(starti + 1,endi + 1, new int[] { start, end + 1 }); } } } //}}} //{{{ fvmdump() method private void fvmdump() { if(Debug.FOLD_VIS_DEBUG) { StringBuffer buf = new StringBuffer("{"); for(int i = 0; i < fvmcount; i++) { if(i != 0) buf.append(','); buf.append(fvm[i]); } buf.append("}"); Log.log(Log.DEBUG,this,"fvm = " + buf); } } //}}} //{{{ showLineRange() method private void showLineRange(int start, int end) { if(Debug.FOLD_VIS_DEBUG) { Log.log(Log.DEBUG,this,"showLineRange(" + start + "," + end + ")"); } for(int i = start; i <= end; i++) { //XXX if(!isLineVisible(i)) { // important: not lineMgr.getScreenLineCount() int screenLines = getScreenLineCount(i); if(firstLine.physicalLine >= i) { firstLine.scrollLine += screenLines; firstLine.callChanged = true; } scrollLineCount.scrollLine += screenLines; scrollLineCount.callChanged = true; } } /* update fold visibility map. */ int starti = fvmget(start); int endi = fvmget(end); if(starti % 2 == 0) { if(endi % 2 == 0) fvmput(starti + 1,endi + 1,null); else { if(endi != fvmcount - 1 && fvm[endi + 1] == end + 1) fvmput(starti + 1,endi + 2,null); else { fvmput(starti + 1,endi,null); fvm[starti + 1] = end + 1; } } } else { if(endi % 2 == 0) { if(starti != -1 && fvm[starti] == start) fvmput(starti,endi + 1,null); else { fvmput(starti + 1,endi,null); fvm[starti + 1] = start; } } else fvmput2(starti,endi,start,end); } lastfvmget = -1; } //}}} //{{{ hideLineRange() method private void hideLineRange(int start, int end) { if(Debug.FOLD_VIS_DEBUG) { Log.log(Log.DEBUG,this,"hideLineRange(" + start + "," + end + ")"); } int i = start; if(!isLineVisible(i)) i = getNextVisibleLine(i); while(i != -1 && i <= end) { int screenLines = lineMgr.getScreenLineCount(i); if(i < firstLine.physicalLine) { firstLine.scrollLine -= screenLines; firstLine.skew = 0; firstLine.callChanged = true; } scrollLineCount.scrollLine -= screenLines; scrollLineCount.callChanged = true; i = getNextVisibleLine(i); } /* update fold visibility map. */ int starti = fvmget(start); int endi = fvmget(end); if(starti % 2 == 0) { if(endi % 2 == 0) fvmput2(starti,endi,start,end); else { fvmput(starti + 1,endi,null); fvm[starti + 1] = start; } } else { if(endi % 2 == 0) { fvmput(starti + 1,endi,null); fvm[starti + 1] = end + 1; } else fvmput(starti + 1,endi + 1,null); } lastfvmget = -1; if(!isLineVisible(firstLine.physicalLine)) { int firstVisible = getFirstVisibleLine(); if(firstLine.physicalLine < firstVisible) { firstLine.physicalLine = firstVisible; firstLine.scrollLine = 0; } else { firstLine.physicalLine = getPrevVisibleLine( firstLine.physicalLine); firstLine.scrollLine -= lineMgr.getScreenLineCount( firstLine.physicalLine); } firstLine.callChanged = true; } } //}}} //{{{ _setScreenLineCount() method private void _setScreenLineCount(int line, int oldCount, int count) { if(!isLineVisible(line)) return; if(firstLine.physicalLine >= line) { if(firstLine.physicalLine == line) firstLine.callChanged = true; else { firstLine.scrollLine += (count - oldCount); firstLine.callChanged = true; } } scrollLineCount.scrollLine += (count - oldCount); scrollLineCount.callChanged = true; } //}}} //}}} //{{{ Anchor class static abstract class Anchor { int physicalLine; int scrollLine; boolean callChanged; boolean callReset; abstract void reset(); abstract void changed(); public String toString() { return getClass().getName() + "[" + physicalLine + "," + scrollLine + "]"; } } //}}} //{{{ ScrollLineCount class class ScrollLineCount extends Anchor { //{{{ changed() method public void changed() { if(Debug.SCROLL_DEBUG) Log.log(Log.DEBUG,this,"changed()"); textArea.updateScrollBars(); textArea.recalculateLastPhysicalLine(); } //}}} //{{{ reset() method public void reset() { if(Debug.SCROLL_DEBUG) Log.log(Log.DEBUG,this,"reset()"); physicalLine = getFirstVisibleLine(); scrollLine = 0; while(physicalLine != -1) { scrollLine += getScreenLineCount(physicalLine); physicalLine = getNextVisibleLine(physicalLine); } physicalLine = buffer.getLineCount(); firstLine.ensurePhysicalLineIsVisible(); textArea.recalculateLastPhysicalLine(); textArea.updateScrollBars(); } //}}} } //}}} //{{{ FirstLine class class FirstLine extends Anchor { int skew; //{{{ changed() method public void changed() { //{{{ Debug code if(Debug.SCROLL_DEBUG) { Log.log(Log.DEBUG,this,"changed() before: " + physicalLine + ":" + scrollLine); } //}}} ensurePhysicalLineIsVisible(); int screenLines = getScreenLineCount(physicalLine); if(skew >= screenLines) skew = screenLines - 1; //{{{ Debug code if(Debug.SCROLL_VERIFY) { int verifyScrollLine = 0; for(int i = 0; i < buffer.getLineCount(); i++) { if(!isLineVisible(i)) continue; if(i >= physicalLine) break; verifyScrollLine += getScreenLineCount(i); } if(verifyScrollLine != scrollLine) { Exception ex = new Exception(scrollLine + ":" + verifyScrollLine); Log.log(Log.ERROR,this,ex); new org.gjt.sp.jedit.gui.BeanShellErrorDialog(null,ex); } } if(Debug.SCROLL_DEBUG) { Log.log(Log.DEBUG,this,"changed() after: " + physicalLine + ":" + scrollLine); } //}}} if(!scrollLineCount.callChanged && !scrollLineCount.callReset) { textArea.updateScrollBars(); textArea.recalculateLastPhysicalLine(); } else { // ScrollLineCount.changed() does the same // thing } } //}}} //{{{ reset() method public void reset() { if(Debug.SCROLL_DEBUG) Log.log(Log.DEBUG,this,"reset()"); String wrap = buffer.getStringProperty("wrap"); softWrap = wrap.equals("soft"); if(textArea.maxLineLen <= 0) { softWrap = false; wrapMargin = 0; } else { // stupidity char[] foo = new char[textArea.maxLineLen]; for(int i = 0; i < foo.length; i++) { foo[i] = ' '; } TextAreaPainter painter = textArea.getPainter(); wrapMargin = (int)painter.getFont().getStringBounds( foo,0,foo.length, painter.getFontRenderContext()) .getWidth(); } scrollLine = 0; int i = getFirstVisibleLine(); for(;;) { if(i >= physicalLine) break; scrollLine += getScreenLineCount(i); int nextLine = getNextVisibleLine(i); if(nextLine == -1) break; else i = nextLine; } physicalLine = i; int screenLines = getScreenLineCount(physicalLine); if(skew >= screenLines) skew = screenLines - 1; textArea.updateScrollBars(); } //}}} //{{{ physDown() method // scroll down by physical line amount void physDown(int amount, int screenAmount) { if(Debug.SCROLL_DEBUG) { Log.log(Log.DEBUG,this,"physDown() start: " + physicalLine + ":" + scrollLine); } skew = 0; if(!isLineVisible(physicalLine)) { int lastVisibleLine = getLastVisibleLine(); if(physicalLine > lastVisibleLine) physicalLine = lastVisibleLine; else { int nextPhysicalLine = getNextVisibleLine(physicalLine); amount -= (nextPhysicalLine - physicalLine); scrollLine += getScreenLineCount(physicalLine); physicalLine = nextPhysicalLine; } } for(;;) { int nextPhysicalLine = getNextVisibleLine( physicalLine); if(nextPhysicalLine == -1) break; else if(nextPhysicalLine > physicalLine + amount) break; else { scrollLine += getScreenLineCount(physicalLine); amount -= (nextPhysicalLine - physicalLine); physicalLine = nextPhysicalLine; } } if(Debug.SCROLL_DEBUG) { Log.log(Log.DEBUG,this,"physDown() end: " + physicalLine + ":" + scrollLine);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -