Mercurial Hosting > luan
changeset 1912:9fa922236aff
highlights
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 16 Apr 2025 21:59:49 -0600 |
parents | cd4c11d7dc7e |
children | 4f0c14fad13b |
files | src/luan/modules/editor/find.luan src/luan/modules/swing/DocumentUpdateListener.java src/luan/modules/swing/LuanDocumentListener.java src/luan/modules/swing/TextAreaLineNumbersLuan.java src/luan/modules/swing/TextAreaLuan.java src/luan/modules/swing/Text_area.luan |
diffstat | 6 files changed, 137 insertions(+), 35 deletions(-) [+] |
line wrap: on
line diff
--- a/src/luan/modules/editor/find.luan Wed Apr 16 09:59:48 2025 -0600 +++ b/src/luan/modules/editor/find.luan Wed Apr 16 21:59:49 2025 -0600 @@ -60,6 +60,7 @@ status_bar.text = "Regex error: "..e.get_message() return end + text_area.set_hightlights(matches) local n_matches = #matches if n_matches == 0 then status_bar.text = "0 matches" @@ -206,6 +207,8 @@ find_panel.visible = visible if visible then find_field.request_focus_in_window() + else + text_area.clear_hightlights() end end function window.find_case_insensitive(_)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/modules/swing/DocumentUpdateListener.java Wed Apr 16 21:59:49 2025 -0600 @@ -0,0 +1,8 @@ +package luan.modules.swing; + +import javax.swing.event.DocumentEvent; + + +public interface DocumentUpdateListener { + void updated(DocumentEvent event); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/modules/swing/LuanDocumentListener.java Wed Apr 16 21:59:49 2025 -0600 @@ -0,0 +1,25 @@ +package luan.modules.swing; + +import javax.swing.event.DocumentListener; +import javax.swing.event.DocumentEvent; + + +public class LuanDocumentListener implements DocumentListener { + private final DocumentUpdateListener dul; + + public LuanDocumentListener(DocumentUpdateListener dul) { + this.dul = dul; + } + + @Override public void changedUpdate(DocumentEvent e) { + dul.updated(e); + } + + @Override public void removeUpdate(DocumentEvent e) { + dul.updated(e); + } + + @Override public void insertUpdate(DocumentEvent e) { + dul.updated(e); + } +}
--- a/src/luan/modules/swing/TextAreaLineNumbersLuan.java Wed Apr 16 09:59:48 2025 -0600 +++ b/src/luan/modules/swing/TextAreaLineNumbersLuan.java Wed Apr 16 21:59:49 2025 -0600 @@ -23,7 +23,7 @@ import goodjava.logging.LoggerFactory; -public class TextAreaLineNumbersLuan extends JPanel implements DocumentListener { +public class TextAreaLineNumbersLuan extends JPanel implements DocumentUpdateListener { private static final Logger logger = LoggerFactory.getLogger(TextAreaLineNumbersLuan.class); private final TextAreaLuan textArea; @@ -43,7 +43,7 @@ } fixWidth(); fixHeights(); - textArea.getDocument().addDocumentListener(new WeakDocumentListener(this)); + textArea.getDocument().addDocumentListener(new WeakDocumentListener(new LuanDocumentListener(this))); textArea.addPropertyChangeListener("lineWrap",lineWrapListener); textArea.addComponentListener(resizeListener); } @@ -125,7 +125,7 @@ boolean changed = false; for( int i=start; i<=end; i++ ) { Component label = getComponent(i); - Dimension size = label.getPreferredSize(); + Dimension size = label.getMaximumSize(); int height; try { height = textArea.getLineHeight(i); @@ -135,8 +135,9 @@ //logger.info("height "+i+" "+height); if( height != size.height ) { changed = true; + //logger.info("width "+i+" "+size.width); Dimension newSize = new Dimension( size.width, height ); - label.setPreferredSize(newSize); + //label.setPreferredSize(newSize); label.setMaximumSize(newSize); } } @@ -163,7 +164,7 @@ } } - @Override public void changedUpdate(DocumentEvent event) { + @Override public void updated(DocumentEvent event) { //logger.info(event.getType().toString()+" "+event.getOffset()+" "+event.getLength()); int n = textArea.getLineCount(); if( lines == n ) { @@ -204,14 +205,6 @@ } } - @Override public void removeUpdate(DocumentEvent e) { - changedUpdate(e); - } - - @Override public void insertUpdate(DocumentEvent e) { - changedUpdate(e); - } - private final PropertyChangeListener lineWrapListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { fixHeights();
--- a/src/luan/modules/swing/TextAreaLuan.java Wed Apr 16 09:59:48 2025 -0600 +++ b/src/luan/modules/swing/TextAreaLuan.java Wed Apr 16 21:59:49 2025 -0600 @@ -1,5 +1,7 @@ package luan.modules.swing; +import java.util.List; +import java.util.Collections; import java.awt.Rectangle; import java.awt.Graphics; import java.awt.Color; @@ -12,11 +14,12 @@ import javax.swing.Timer; import javax.swing.text.DefaultCaret; import javax.swing.text.BadLocationException; +import javax.swing.event.DocumentEvent; import goodjava.logging.Logger; import goodjava.logging.LoggerFactory; -public class TextAreaLuan extends JTextArea { +public class TextAreaLuan extends JTextArea implements DocumentUpdateListener { private static final Logger logger = LoggerFactory.getLogger(TextAreaLuan.class); private static final DefaultCaret flatLafCaret = new DefaultCaret() { @@ -38,7 +41,19 @@ } }; + public static class Range { + private final int start; + private final int end; + + public Range(int start,int end) { + this.start = start; + this.end = end; + } + } + private boolean showWhitespace = false; + private List<Range> highlights = Collections.emptyList(); + private static final Color highlightColor = new Color(0x2dada3); public TextAreaLuan() { super(); @@ -46,6 +61,7 @@ if( UIManager.getLookAndFeel().getName().startsWith("FlatLaf") ) { setCaret(flatLafCaret); } + getDocument().addDocumentListener(new WeakDocumentListener(new LuanDocumentListener(this))); } public int getLineHeight(int line) throws BadLocationException { @@ -68,31 +84,79 @@ repaint(); } + public void setHightlights(List<Range> highlights) { + this.highlights = highlights; + repaint(); + } + + public void clearHighlights() { + if( highlights.size() > 0 ) + setHightlights(Collections.emptyList()); + } + + @Override public void updated(DocumentEvent event) { + clearHighlights(); + } + @Override protected void paintComponent(Graphics g) { super.paintComponent(g); - if( !showWhitespace ) - return; - g.setColor(Color.LIGHT_GRAY); - String text = getText(); - int ascent = g.getFontMetrics().getAscent(); - Rectangle visible = getVisibleRect(); - for( int pos=0; pos<text.length(); pos++ ) { - char ch = text.charAt(pos); - String symbol; - switch(ch) { - case ' ': symbol = "·"; break; - case '\t': symbol = "→"; break; - case '\n': symbol = "¶"; break; - default: continue; + try { + if( showWhitespace ) { + g.setColor(Color.LIGHT_GRAY); + String text = getText(); + int ascent = g.getFontMetrics().getAscent(); + Rectangle visible = getVisibleRect(); + for( int pos=0; pos<text.length(); pos++ ) { + char ch = text.charAt(pos); + String symbol; + switch(ch) { + case ' ': symbol = "·"; break; + case '\t': symbol = "→"; break; + case '\n': symbol = "¶"; break; + default: continue; + } + Rectangle r = modelToView(pos); + if( visible.contains(r) ) + g.drawString( symbol, r.x, r.y + ascent ); + } } - Rectangle r; - try { - r = modelToView(pos); - } catch(BadLocationException e) { - throw new RuntimeException(e); + g.setColor(highlightColor); + for( Range range : highlights ) { + Rectangle r1 = modelToView(range.start); + Rectangle r2 = modelToView(range.end); + if( r1.y == r2.y ) { + g.drawRect( r1.x, r1.y, r2.x - r1.x, r1.height ); + } else { + g.drawLine( r1.x, r1.y, r1.x, r1.y+r1.height ); + g.drawLine( r2.x, r2.y, r2.x, r2.y+r2.height ); + for( int i=range.start; i<range.end; i++ ) { + Rectangle r = modelToView(i); + if( r1.y == r.y ) { + r2 = r; + } else { + int x1 = r1.x; + int x2 = r2.x + r2.width; + int y = r1.y; + g.drawLine( x1, y, x2, y ); + y += r1.height; + g.drawLine( x1, y, x2, y ); + r1 = r; + r2 = r; + } + } + r2 = modelToView(range.end); + if( r2.x > r1.x ) { + int x1 = r1.x; + int x2 = r2.x; + int y = r1.y; + g.drawLine( x1, y, x2, y ); + y += r1.height; + g.drawLine( x1, y, x2, y ); + } + } } - if( visible.contains(r) ) - g.drawString( symbol, r.x, r.y + ascent ); + } catch(BadLocationException e) { + throw new RuntimeException(e); } }
--- a/src/luan/modules/swing/Text_area.luan Wed Apr 16 09:59:48 2025 -0600 +++ b/src/luan/modules/swing/Text_area.luan Wed Apr 16 21:59:49 2025 -0600 @@ -1,6 +1,7 @@ local Luan = require "luan:Luan.luan" local error = Luan.error local set_metatable = Luan.set_metatable or error() +local ipairs = Luan.ipairs or error() local Utils = require "luan:swing/Utils.luan" local fail = Utils.fail or error() local make_metatable = Utils.make_metatable or error() @@ -103,6 +104,14 @@ return jtext_area.getDocument().replace(start_pos-1,length,text) end) end + function text_area.set_hightlights(hightlights) + local list = {} + for _, hightlight in ipairs(hightlights) do + list[#list+1] = TextAreaLuan.Range.new(hightlight.start-1,hightlight.end_-1) + end + jtext_area.setHightlights(list) + end + text_area.clear_hightlights = jtext_area.clearHighlights set_metatable(text_area,mt) return text_area end