live data progress

This commit is contained in:
rusefillc 2022-01-28 23:24:34 -05:00
parent d20db70a28
commit c92725d50a
4 changed files with 215 additions and 15 deletions

View File

@ -0,0 +1,156 @@
package com.camick;
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
/*
* A collection of static methods that provide added functionality for
* text components (most notably, JTextArea and JTextPane)
*
* See also: javax.swing.text.Utilities
*/
public class RXTextUtilities
{
/*
* Attempt to center the line containing the caret at the center of the
* scroll pane.
*
* @param component the text component in the sroll pane
*/
public static void centerLineInScrollPane(JTextComponent component)
{
Container container = SwingUtilities.getAncestorOfClass(JViewport.class, component);
if (container == null) return;
try
{
Rectangle r = component.modelToView(component.getCaretPosition());
JViewport viewport = (JViewport)container;
int extentHeight = viewport.getExtentSize().height;
int viewHeight = viewport.getViewSize().height;
int y = Math.max(0, r.y - ((extentHeight - r.height) / 2));
y = Math.min(y, viewHeight - extentHeight);
viewport.setViewPosition(new Point(0, y));
}
catch(BadLocationException ble) {}
}
/*
* Return the column number at the Caret position.
*
* The column returned will only make sense when using a
* Monospaced font.
*/
public static int getColumnAtCaret(JTextComponent component)
{
// Since we assume a monospaced font we can use the width of a single
// character to represent the width of each character
FontMetrics fm = component.getFontMetrics( component.getFont() );
int characterWidth = fm.stringWidth( "0" );
int column = 0;
try
{
Rectangle r = component.modelToView( component.getCaretPosition() );
int width = r.x - component.getInsets().left;
column = width / characterWidth;
}
catch(BadLocationException ble) {}
return column + 1;
}
/*
* Return the line number at the Caret position.
*/
public static int getLineAtCaret(JTextComponent component)
{
int caretPosition = component.getCaretPosition();
Element root = component.getDocument().getDefaultRootElement();
return root.getElementIndex( caretPosition ) + 1;
}
/*
* Return the number of lines of text in the Document
*/
public static int getLines(JTextComponent component)
{
Element root = component.getDocument().getDefaultRootElement();
return root.getElementCount();
}
/*
* Position the caret at the start of a line.
*/
public static void gotoStartOfLine(JTextComponent component, int line)
{
int startOfLineOffset = getStartOfLineOffset(component, line);
component.setCaretPosition( startOfLineOffset );
}
public static int getStartOfLineOffset(JTextComponent component, int line) {
Element root = component.getDocument().getDefaultRootElement();
line = Math.max(line, 1);
line = Math.min(line, root.getElementCount());
int startOfLineOffset = root.getElement( line - 1 ).getStartOffset();
return startOfLineOffset;
}
/*
* Position the caret on the first word of a line.
*/
public static void gotoFirstWordOnLine(final JTextComponent component, int line)
{
gotoStartOfLine(component, line);
// The following will position the caret at the start of the first word
try
{
int position = component.getCaretPosition();
String first = component.getDocument().getText(position, 1);
if (Character.isWhitespace(first.charAt(0)))
{
component.setCaretPosition(Utilities.getNextWord(component, position));
}
}
catch(Exception e) {}
}
/*
* Return the number of lines of text, including wrapped lines.
*/
public static int getWrappedLines(JTextArea component)
{
View view = component.getUI().getRootView(component).getView(0);
int preferredHeight = (int)view.getPreferredSpan(View.Y_AXIS);
int lineHeight = component.getFontMetrics( component.getFont() ).getHeight();
return preferredHeight / lineHeight;
}
/*
* Return the number of lines of text, including wrapped lines.
*/
public static int getWrappedLines(JTextComponent component)
{
int lines = 0;
View view = component.getUI().getRootView(component).getView(0);
int paragraphs = view.getViewCount();
for (int i = 0; i < paragraphs; i++)
{
lines += view.getView(i).getViewCount();
}
return lines;
}
}

View File

@ -63,7 +63,6 @@ public class CodeWalkthrough {
} else { } else {
unqualifiedIdContext = idExpressionContext.unqualifiedId(); unqualifiedIdContext = idExpressionContext.unqualifiedId();
} }
System.out.println(declaratorid.getText());
functions.add(unqualifiedIdContext); functions.add(unqualifiedIdContext);
} }

View File

@ -106,6 +106,14 @@ public class LiveDataParserPanel {
} }
} }
public ParseResult getParseResult() {
return parseResult;
}
public JTextPane getText() {
return text;
}
@NotNull @NotNull
public static String getContent(Class<?> clazz, String fileName) throws IOException, URISyntaxException { public static String getContent(Class<?> clazz, String fileName) throws IOException, URISyntaxException {
String contentOrNull = getContentOrNull(clazz, fileName); String contentOrNull = getContentOrNull(clazz, fileName);

View File

@ -1,12 +1,14 @@
package com.rusefi.ui; package com.rusefi.ui;
import com.camick.RXTextUtilities;
import com.rusefi.CodeWalkthrough; import com.rusefi.CodeWalkthrough;
import com.rusefi.config.Field; import com.rusefi.config.Field;
import com.rusefi.core.Pair;
import com.rusefi.core.Sensor; import com.rusefi.core.Sensor;
import com.rusefi.enums.live_data_e; import com.rusefi.enums.live_data_e;
import com.rusefi.ldmp.StateDictionary; import com.rusefi.ldmp.StateDictionary;
import com.rusefi.livedata.LiveDataParserPanel; import com.rusefi.livedata.LiveDataParserPanel;
import com.rusefi.livedata.ParseResult;
import com.rusefi.livedata.generated.CPP14Parser;
import com.rusefi.ui.util.UiUtils; import com.rusefi.ui.util.UiUtils;
import com.rusefi.ui.widgets.IntGaugeLabel; import com.rusefi.ui.widgets.IntGaugeLabel;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
@ -14,14 +16,11 @@ import org.jetbrains.annotations.NotNull;
import org.putgemin.VerticalFlowLayout; import org.putgemin.VerticalFlowLayout;
import javax.swing.*; import javax.swing.*;
import javax.swing.event.TreeSelectionEvent; import javax.swing.text.BadLocationException;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.*; import javax.swing.tree.*;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import static com.rusefi.autoupdate.AutoupdateUtil.wrap;
/** /**
* Andrey Belomutskiy, (c) 2013-2020 * Andrey Belomutskiy, (c) 2013-2020
@ -51,13 +50,18 @@ public class LiveDataPane {
for (live_data_e view : live_data_e.values()) { for (live_data_e view : live_data_e.values()) {
String fileName = StateDictionary.INSTANCE.getFileName(view) + CPP_SUFFIX; String fileName = StateDictionary.INSTANCE.getFileName(view) + CPP_SUFFIX;
Field[] values = StateDictionary.INSTANCE.getFields(view); Field[] values = StateDictionary.INSTANCE.getFields(view);
JPanel liveDataParserContent = LiveDataParserPanel.createLiveDataParserPanel(uiContext, view, values, fileName).getContent(); LiveDataParserPanel liveDataParserPanel = LiveDataParserPanel.createLiveDataParserPanel(uiContext, view, values, fileName);
ParseResult parseResult = liveDataParserPanel.getParseResult();
JPanel liveDataParserContent = liveDataParserPanel.getContent();
DefaultMutableTreeNode child = new DefaultMutableTreeNode(fileName); DefaultMutableTreeNode child = new DefaultMutableTreeNode(fileName);
child.setUserObject(new PanelAndName(liveDataParserContent, fileName)); child.setUserObject(new PanelAndName(liveDataParserContent, fileName));
DefaultMutableTreeNode method1 = new DefaultMutableTreeNode();
method1.setUserObject(new Pair<String, String>(fileName, "method")); for (CPP14Parser.UnqualifiedIdContext functionId : parseResult.getFunctions()) {
child.add(method1); DefaultMutableTreeNode methodNode = new DefaultMutableTreeNode();
methodNode.setUserObject(new SpecificMethod(liveDataParserPanel, functionId));
child.add(methodNode);
}
root.add(child); root.add(child);
@ -70,17 +74,31 @@ public class LiveDataPane {
MouseListener ml = new MouseAdapter() { MouseListener ml = new MouseAdapter() {
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
tree.getLastSelectedPathComponent();
Object payload = node.getUserObject(); Object payload = node.getUserObject();
if (payload instanceof PanelAndName) { if (payload instanceof PanelAndName) {
PanelAndName panel = (PanelAndName) payload; PanelAndName panel = (PanelAndName) payload;
scroll.getVerticalScrollBar().setValue(panel.panel.getLocation().y); scrollToPanel(panel.panel, 0);
// we want focus there so that mouse wheel scrolling would be active } else if (payload instanceof SpecificMethod) {
scroll.requestFocus(); SpecificMethod method = (SpecificMethod) payload;
JTextPane jTextPane = method.liveDataParserPanel.getText();
int position = RXTextUtilities.getStartOfLineOffset(jTextPane, method.method.getStart().getLine());
Rectangle r;
try {
r = jTextPane.modelToView(position);
} catch (BadLocationException ex) {
return;
}
scrollToPanel(method.liveDataParserPanel.getContent(), r.y);
} }
} }
private void scrollToPanel(JPanel panel, int yOffset) {
scroll.getVerticalScrollBar().setValue(panel.getLocation().y + yOffset);
// we want focus there so that mouse wheel scrolling would be active
scroll.requestFocus();
}
}; };
tree.addMouseListener(ml); tree.addMouseListener(ml);
content.add(tree, BorderLayout.WEST); content.add(tree, BorderLayout.WEST);
@ -157,4 +175,23 @@ public class LiveDataPane {
return name; return name;
} }
} }
static class SpecificMethod {
private final LiveDataParserPanel liveDataParserPanel;
private final CPP14Parser.UnqualifiedIdContext method;
public SpecificMethod(LiveDataParserPanel liveDataParserPanel, CPP14Parser.UnqualifiedIdContext method) {
this.liveDataParserPanel = liveDataParserPanel;
this.method = method;
}
public LiveDataParserPanel getLiveDataParserPanel() {
return liveDataParserPanel;
}
@Override
public String toString() {
return method.getText();
}
}
} }