Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
4b9b682
only blink selection highlighter on one token at a time
supersaiyansubtlety Oct 22, 2025
456caa7
remove initial delay from SelectionHighlightHandler
supersaiyansubtlety Oct 22, 2025
b9d24a6
make selection highlight blink count and blink delay configurable
supersaiyansubtlety Oct 22, 2025
b6dfe29
on opening new tab, wait for source to be set before highlighting fir…
supersaiyansubtlety Oct 23, 2025
c48331f
use IntegerRange instead of BoundedNumber
supersaiyansubtlety Oct 26, 2025
a1a5146
add gui for selection highlight configs
supersaiyansubtlety Oct 27, 2025
807faab
replace 'token' with 'entry' in strings explaining selection highligh…
supersaiyansubtlety Oct 27, 2025
d0c9b7b
replace blink dialog with radio selector
supersaiyansubtlety Nov 2, 2025
7c3ce8a
add elipses to blink delay menu item because it opens a dialog
supersaiyansubtlety Nov 2, 2025
1740578
fix GuiUtil::createIntConfigRadioMenu's action listener
supersaiyansubtlety Nov 18, 2025
cbd4bf0
Merge branch 'develop/2.8' into improve-selection-highlighting
supersaiyansubtlety Dec 12, 2025
c5c15fe
add POC MarkableScrollPane
supersaiyansubtlety Oct 26, 2025
dba33e4
rename and make abstract BaseEditorPanel -> AbstractEditorPanel
supersaiyansubtlety Oct 26, 2025
78af287
add markers for EditorPanel tokens
supersaiyansubtlety Oct 26, 2025
37d2b51
remove debug code from MarkableScrollPane
supersaiyansubtlety Oct 26, 2025
9d480d8
make markers for each token type toggleable
supersaiyansubtlety Oct 26, 2025
0af32ba
allow configuring markers via the gui
supersaiyansubtlety Oct 26, 2025
c1c1cdc
navigate to entry on marker click
supersaiyansubtlety Oct 27, 2025
d13e0e1
tweak paintersByPos order handling, cleanup
supersaiyansubtlety Oct 29, 2025
3133dc1
refactor+rename MarkablePredicate -> MarkerManager
supersaiyansubtlety Oct 29, 2025
0fee955
implement MarkableScrollPane.MarkerListener and use it to show entry …
supersaiyansubtlety Oct 30, 2025
2f18c90
cleanup and javadoc MarkableScrollPane
supersaiyansubtlety Oct 30, 2025
fb2f3cf
rename EntryMarkersSection.interactable -> tooltip and implement it
supersaiyansubtlety Oct 30, 2025
e872de2
don't mark constructors when only marking declarations
supersaiyansubtlety Oct 30, 2025
260db10
add separator between onlyMarkDeclarations and token type toggles
supersaiyansubtlety Oct 30, 2025
936b8ac
add new test input class
supersaiyansubtlety Oct 30, 2025
1ece814
make max markers per line configurable
supersaiyansubtlety Oct 31, 2025
3ec53af
eliminate marker overlap
supersaiyansubtlety Nov 1, 2025
a6bffe6
account for existing markers with differing positions but equal scale…
supersaiyansubtlety Nov 1, 2025
6b6d4a8
add WIP EditorPanel.MarkerTooltip
supersaiyansubtlety Nov 1, 2025
4db9659
fix marker max top + min bottom
supersaiyansubtlety Nov 1, 2025
6575a38
refine position and size of marker tooltip
supersaiyansubtlety Nov 1, 2025
708af16
pass marker area to repaint method
supersaiyansubtlety Nov 1, 2025
535f16b
fully repaint in component listener
supersaiyansubtlety Nov 1, 2025
8b1117a
attach a LineIndexer to DecompiledClassSource
supersaiyansubtlety Nov 1, 2025
236548a
remove isBounded check from SimpleSnippetPanel
supersaiyansubtlety Nov 1, 2025
553f5c7
don't refresh markers on componentShown (causes unecessary repaint)
supersaiyansubtlety Nov 2, 2025
00edab9
use GuiUtil's createIntConfigRadioMenu in EntryMarkersMenu
supersaiyansubtlety Nov 2, 2025
947301b
shift scaledPos down by this.areaY
supersaiyansubtlety Nov 9, 2025
87a406b
use jspecify annotations in new classes
supersaiyansubtlety Nov 18, 2025
e69af0e
checkstyle
supersaiyansubtlety Nov 18, 2025
c835918
copy and dispose graphics in MarkableScrollPane::paint
supersaiyansubtlety Dec 4, 2025
bf021ff
extract GuiUtil.TRANSPARENT
supersaiyansubtlety Dec 4, 2025
683b994
start FlexGridLayout with Constraints
supersaiyansubtlety Nov 24, 2025
9cf8273
extract ConstrainedGrid from FlexGridLayout
supersaiyansubtlety Nov 24, 2025
bd6467d
promote FlexGridLayout.Constraints -> FlexGridConstraints
supersaiyansubtlety Nov 24, 2025
804877d
move Alignment from FlexGridLayout to FlexGridConstraints
supersaiyansubtlety Nov 24, 2025
c95f178
implement ...LayouSize methods and size caching
supersaiyansubtlety Nov 24, 2025
ab8ffbb
first complete pass at alignment; fill/alignment not yet respected
supersaiyansubtlety Nov 26, 2025
f398a54
extract FlexGridLayout.AxisOperation to replace `boolean xAxis` spagh…
supersaiyansubtlety Nov 26, 2025
edc8428
setup gui visualization sourceSet+task to open a window
supersaiyansubtlety Nov 26, 2025
92fedee
minor tweaks
supersaiyansubtlety Nov 26, 2025
34d540f
move unsupported constructor to top
supersaiyansubtlety Nov 26, 2025
ee10a19
add FlexGridRelativeRowVisualiser
supersaiyansubtlety Nov 28, 2025
acd65ca
add FlexGridColumnVisualiser
supersaiyansubtlety Nov 28, 2025
825d2b7
use Visualizer interface instead of making visualizers extend JFrame
supersaiyansubtlety Nov 28, 2025
8ff3245
add FlexGridOverlapVisualiser
supersaiyansubtlety Nov 28, 2025
cc1296b
quiltify FlexGridGridVisualiser
supersaiyansubtlety Nov 28, 2025
b9a1b0d
remove print
supersaiyansubtlety Nov 28, 2025
d1f71e4
fix passing an incorrect coord in layoutAxisImpl
supersaiyansubtlety Nov 28, 2025
845a3d3
reject TODO
supersaiyansubtlety Nov 28, 2025
8fdfd43
package flex grid
supersaiyansubtlety Nov 28, 2025
daaac2a
implement filling
supersaiyansubtlety Nov 28, 2025
7f4453d
fix prioritization in allocateCellSpace
supersaiyansubtlety Nov 28, 2025
7019ac8
implement alignment
supersaiyansubtlety Nov 28, 2025
437a428
make getSelf package-private
supersaiyansubtlety Nov 29, 2025
814c904
ignore unused in FlexGridConstraints
supersaiyansubtlety Nov 29, 2025
7745223
package flex grid visualizers
supersaiyansubtlety Nov 29, 2025
17d030b
add more FlexGridConstraints priority setters
supersaiyansubtlety Nov 29, 2025
49d315f
convert CartesianOperations to enum
supersaiyansubtlety Nov 29, 2025
fa59ba7
add some javadocs to visualizer stuff
supersaiyansubtlety Nov 29, 2025
2fbb692
javadoc visualizeQuilt
supersaiyansubtlety Nov 29, 2025
7e1078f
javadoc FlexGridLayout (class only), start javadocing FlexGridConstra…
supersaiyansubtlety Nov 29, 2025
d3d2289
dequeue from prioritized instead of iterating because iteration order…
supersaiyansubtlety Nov 29, 2025
59b079c
javadoc FlexGridConstraints
supersaiyansubtlety Dec 2, 2025
5f4ed48
fix allocating space for components with excess extent
supersaiyansubtlety Dec 6, 2025
5736910
reuse extendedCellSpan calculation
supersaiyansubtlety Dec 6, 2025
d73e4dd
center components in container when filling
supersaiyansubtlety Dec 6, 2025
fb844fa
tweak javadoc
supersaiyansubtlety Dec 6, 2025
ef1c1f8
improve javadoc wording
supersaiyansubtlety Dec 6, 2025
97be445
improve input verification
supersaiyansubtlety Dec 6, 2025
fe903d7
improve VisualBox labeling
supersaiyansubtlety Dec 6, 2025
db71080
add FlexGridPriorityFillVisualizer
supersaiyansubtlety Dec 6, 2025
95beb94
add FlexGridSparseVisualizer
supersaiyansubtlety Dec 6, 2025
9685f8e
add FlexGridVVisualizer
supersaiyansubtlety Dec 6, 2025
080e5ea
fix empty cells in non-empty rows/columns collapsing
supersaiyansubtlety Dec 6, 2025
ce1428c
rename visualizer
supersaiyansubtlety Dec 6, 2025
c721379
add FlexGridCheckersVisualizer
supersaiyansubtlety Dec 6, 2025
eab46d7
fix using xExtent instead of yExtent in Sizes::calculate
supersaiyansubtlety Dec 6, 2025
4118ed2
add FlexGridTetrisVisualizer
supersaiyansubtlety Dec 6, 2025
6cf9ee9
add FlexGridPriorityScrollPanes
supersaiyansubtlety Dec 6, 2025
e332281
rename FlexGridPriorityScrollPanes -> FlexGridPriorityScrollPanesVisu…
supersaiyansubtlety Dec 7, 2025
13e4ce0
fix not tracking component positions in ConstrainedGrid, preventing r…
supersaiyansubtlety Dec 7, 2025
ed2ac17
cache immutable Size instead of mutable Dimension
supersaiyansubtlety Dec 7, 2025
2e78077
fix several bugs in FlexGridLayout
supersaiyansubtlety Dec 8, 2025
dc68fb6
fix relative FlexGridLayout components
supersaiyansubtlety Dec 8, 2025
00dbc54
add note that FlexGridLayout does not support insets
supersaiyansubtlety Dec 8, 2025
ec91fda
repaint before packing
supersaiyansubtlety Dec 8, 2025
6dcd10b
make 'no package', 'synthetic', and 'anonymous' translatable
supersaiyansubtlety Dec 8, 2025
8c7aab4
account for screen insets when positioning EntryTooltip (tooltip does…
supersaiyansubtlety Dec 9, 2025
04d9b64
use ImmutableMaps with correct order instead of SortedMaps for cellSpans
supersaiyansubtlety Dec 9, 2025
9a34188
add SmartScrollPane and use it in DeclarationSnippetPanel
supersaiyansubtlety Dec 10, 2025
69fb36f
make MarkableScrollPane extend SmartScrollPane
supersaiyansubtlety Dec 10, 2025
4d0a28a
implement FlexGridConstraints.Relative.Placement
supersaiyansubtlety Dec 11, 2025
972ada8
improve javadoc
supersaiyansubtlety Dec 11, 2025
68b2b0f
extract common part of CartesianOperations and give ConstrainedGrid a…
supersaiyansubtlety Dec 12, 2025
25596ce
use relative constraints in EntryTooltip
supersaiyansubtlety Dec 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions enigma-swing/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ plugins {
alias(libs.plugins.shadow)
}

sourceSets {
guiVisualization
}

configurations {
guiVisualizationRuntimeClasspath.extendsFrom runtimeClasspath
guiVisualizationCompileClasspath.extendsFrom compileClasspath
}

dependencies {
implementation project(':enigma')
implementation project(':enigma-server')
Expand All @@ -32,7 +41,9 @@ dependencies {
implementation libs.swing.dpi
implementation libs.fontchooser
implementation libs.javaparser

testImplementation(testFixtures(project(':enigma')))
guiVisualizationImplementation(project)
}

application {
Expand Down Expand Up @@ -97,6 +108,20 @@ project(":enigma").file("src/test/java/org/quiltmc/enigma/input").listFiles().ea

registerTestTask("complete")

final guiVisualizationJar = tasks.register('guiVisualizationJar', Jar.class) {
from(sourceSets.guiVisualization.output)

archiveFileName = 'gui-visualization.jar'
destinationDirectory = layout.buildDirectory.map { it.dir('gui-visualization') }
}

tasks.register('visualizeGui', JavaExec) {
dependsOn(guiVisualizationJar)

classpath = sourceSets.guiVisualization.runtimeClasspath
mainClass = 'org.quilt.internal.gui.visualization.Main'
}

void registerPrintColorKeyGroupsMapCode(String lafsName, LookAndFeel... lookAndFeels) {
tasks.register("print" + lafsName + "ColorKeyGroupsMapCode", PrintColorKeyGroupsMapCodeTask) { task ->
task.lookAndFeels = lookAndFeels as List
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package org.quilt.internal.gui.visualization;

import org.quilt.internal.gui.visualization.flex_grid.FlexGridAlignAndFillVisualizer;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridAlignmentVisualizer;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridCheckersVisualizer;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridColumnVisualiser;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridDefaultRowVisualiser;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridDiagonalBricksVisualizer;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridFillVisualizer;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridExtentOverlapVisualiser;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridPriorityFillVisualizer;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridPriorityScrollPanesVisualizer;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridPriorityVisualizer;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridQuiltVisualiser;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridRelativeExtentOverlapVisualizer;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridRelativeRowsVisualizer;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridSparseVisualizer;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridGreaterVisualizer;
import org.quilt.internal.gui.visualization.flex_grid.FlexGridTetrisVisualizer;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.concurrent.atomic.AtomicReference;

/**
* The main entrypoint for {@link Visualizer}s.
*
* <p> Opens a window full of buttons that open visualizer windows.
*/
public final class Main {
private Main() {
throw new UnsupportedOperationException();
}

private static final JFrame WINDOW = new JFrame("Gui Visualization");

// bootstrap
static {
registerVisualizer(new FlexGridDefaultRowVisualiser());
registerVisualizer(new FlexGridColumnVisualiser());
registerVisualizer(new FlexGridQuiltVisualiser());
registerVisualizer(new FlexGridExtentOverlapVisualiser());
registerVisualizer(new FlexGridFillVisualizer());
registerVisualizer(new FlexGridAlignmentVisualizer());
registerVisualizer(new FlexGridAlignAndFillVisualizer());
registerVisualizer(new FlexGridPriorityVisualizer());
registerVisualizer(new FlexGridPriorityFillVisualizer());
registerVisualizer(new FlexGridSparseVisualizer());
registerVisualizer(new FlexGridGreaterVisualizer());
registerVisualizer(new FlexGridCheckersVisualizer());
registerVisualizer(new FlexGridDiagonalBricksVisualizer());
registerVisualizer(new FlexGridTetrisVisualizer());
registerVisualizer(new FlexGridPriorityScrollPanesVisualizer());
registerVisualizer(new FlexGridRelativeRowsVisualizer());
registerVisualizer(new FlexGridRelativeExtentOverlapVisualizer());
}

private static void position(Window window) {
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
final int x = (screenSize.width - window.getWidth()) / 2;
final int y = (screenSize.height - window.getHeight()) / 2;

window.setLocation(x, y);
}

public static void main(String[] args) {
WINDOW.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

WINDOW.setLayout(new FlowLayout());

final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
final int width = screenSize.width * 2 / 3;
final int height = screenSize.height * 2 / 3;
final int x = (screenSize.width - width) / 2;
final int y = (screenSize.height - height) / 2;

WINDOW.setBounds(x, y, width, height);
WINDOW.setVisible(true);
}

private static void registerVisualizer(Visualizer visualizer) {
final JButton button = new JButton(visualizer.getTitle());
final AtomicReference<JFrame> currentWindow = new AtomicReference<>();

button.addActionListener(e -> {
final JFrame window = currentWindow.updateAndGet(old -> {
if (old != null) {
old.dispose();
}

return new JFrame(visualizer.getTitle());
});

visualizer.visualize(window);

window.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
window.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
final JFrame window = currentWindow.get();
if (window == null || !window.isDisplayable()) {
WINDOW.requestFocus();
}
}
});

position(window);
window.setVisible(true);
});

WINDOW.add(button);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.quilt.internal.gui.visualization;

import javax.swing.JFrame;

/**
* A visualizer populates a window with content to help visualize what GUI code does.
*
* <p> Visualizers are registered in {@link Main}.
*/
public interface Visualizer {
/**
* The title of the visualizer.
*
* <p> Used by {@link Main} for the visualizer's button text and window titles.
*/
String getTitle();

/**
* Populates the passed {@code window} with content for visualization.
*/
void visualize(JFrame window);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.quilt.internal.gui.visualization.flex_grid;

import org.quilt.internal.gui.visualization.Visualizer;
import org.quilt.internal.gui.visualization.util.VisualUtils;

import javax.swing.JFrame;

public class FlexGridAlignAndFillVisualizer implements Visualizer {
@Override
public String getTitle() {
return "Flex Grid Align & Fill";
}

@Override
public void visualize(JFrame window) {
VisualUtils.visualizeFlexGridQuilt(
window,
c -> c.fillNone().alignTopLeft(),
c -> c.fillOnlyY().alignTopCenter(),
c -> c.fillNone().alignTopRight(),

c -> c.fillOnlyX().alignCenterLeft(),
c -> c.fillBoth().alignCenter(),
c -> c.fillOnlyX().alignCenterRight(),

c -> c.fillNone().alignBottomLeft(),
c -> c.fillOnlyY().alignBottomCenter(),
c -> c.fillNone().alignBottomRight()
);

window.pack();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.quilt.internal.gui.visualization.flex_grid;

import org.quilt.internal.gui.visualization.Visualizer;
import org.quilt.internal.gui.visualization.util.VisualBox;
import org.quilt.internal.gui.visualization.util.VisualUtils;
import org.quiltmc.enigma.gui.util.layout.flex_grid.constraints.FlexGridConstraints;
import org.quiltmc.enigma.gui.util.layout.flex_grid.constraints.FlexGridConstraints.Absolute;

import javax.swing.JFrame;

public class FlexGridAlignmentVisualizer implements Visualizer {
private static final int SPACER_SIZE = (int) (VisualBox.DEFAULT_SIZE * 1.2);

private static VisualBox createSpacer() {
return VisualBox.ofFixed(SPACER_SIZE);
}

@Override
public String getTitle() {
return "Flex Grid Alignment";
}

@Override
public void visualize(JFrame window) {
VisualUtils.visualizeFlexGridQuilt(
window,
Absolute::alignTopLeft, Absolute::alignTopCenter, Absolute::alignTopRight,
Absolute::alignCenterLeft, Absolute::alignCenter, Absolute::alignCenterRight,
Absolute::alignBottomLeft, Absolute::alignBottomCenter, Absolute::alignBottomRight
);

final Absolute constraints = FlexGridConstraints.createAbsolute();
window.add(createSpacer(), constraints);
window.add(createSpacer(), constraints.nextColumn());
window.add(createSpacer(), constraints.nextColumn());

window.add(createSpacer(), constraints.nextRow());
window.add(createSpacer(), constraints.nextColumn());
window.add(createSpacer(), constraints.nextColumn());

window.add(createSpacer(), constraints.nextRow());
window.add(createSpacer(), constraints.nextColumn());
window.add(createSpacer(), constraints.nextColumn());

window.pack();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.quilt.internal.gui.visualization.flex_grid;

import org.quilt.internal.gui.visualization.Visualizer;
import org.quilt.internal.gui.visualization.util.VisualBox;
import org.quiltmc.enigma.gui.util.layout.flex_grid.FlexGridLayout;
import org.quiltmc.enigma.gui.util.layout.flex_grid.constraints.FlexGridConstraints;

import javax.swing.JFrame;
import java.awt.Color;

public class FlexGridCheckersVisualizer implements Visualizer {
private static final int BOARD_SIZE = 8;

@Override
public String getTitle() {
return "Flex Grid Checkers";
}

@Override
public void visualize(JFrame window) {
window.setLayout(new FlexGridLayout());

final FlexGridConstraints.Absolute constraints = FlexGridConstraints.createAbsolute();

boolean placeOnEvenY = false;
for (int x = 0; x < BOARD_SIZE; x++) {
for (int y = 0; y < BOARD_SIZE; y++) {
if (placeOnEvenY == (y % 2 == 0)) {
window.add(VisualBox.of(Color.RED), constraints.pos(x, y));
}
}

placeOnEvenY = !placeOnEvenY;
}

window.pack();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.quilt.internal.gui.visualization.flex_grid;

import org.quilt.internal.gui.visualization.Visualizer;
import org.quiltmc.enigma.gui.util.layout.flex_grid.constraints.FlexGridConstraints;
import org.quiltmc.enigma.gui.util.layout.flex_grid.FlexGridLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class FlexGridColumnVisualiser implements Visualizer {
@Override
public String getTitle() {
return "Flex Grid Column";
}

@Override
public void visualize(JFrame window) {
window.setLayout(new FlexGridLayout());

final FlexGridConstraints.Absolute constraints = FlexGridConstraints.createAbsolute();
window.add(new JLabel("Label 1"), constraints);
window.add(new JLabel("Label 2"), constraints.nextRow());
window.add(new JLabel("Label 3"), constraints.nextRow());

window.pack();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.quilt.internal.gui.visualization.flex_grid;

import org.quilt.internal.gui.visualization.Visualizer;
import org.quiltmc.enigma.gui.util.layout.flex_grid.FlexGridLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class FlexGridDefaultRowVisualiser implements Visualizer {
@Override
public String getTitle() {
return "Flex Grid Default Row";
}

@Override
public void visualize(JFrame window) {
window.setLayout(new FlexGridLayout());

window.add(new JLabel("Label 1"));
window.add(new JLabel("Label 2"));
window.add(new JLabel("Label 3"));

window.pack();
}
}
Loading