Skip to content

Commit

Permalink
refactor: abstract away the text bound aspect of the ControlFlowLines…
Browse files Browse the repository at this point in the history
… feature
  • Loading branch information
jumanji144 committed Jul 14, 2024
1 parent 30f5f2d commit cb5aaab
Show file tree
Hide file tree
Showing 2 changed files with 239 additions and 196 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package software.coley.recaf.ui.control.richtext.linegraphics;

import jakarta.annotation.Nonnull;
import javafx.beans.binding.Bindings;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Pos;
import javafx.scene.layout.StackPane;
import org.openrewrite.jgit.annotations.NonNull;
import software.coley.recaf.ui.control.VirtualizedScrollPaneWrapper;
import software.coley.recaf.ui.control.richtext.Editor;
import software.coley.recaf.util.FxThreadUtil;
import software.coley.recaf.util.SceneUtils;

public abstract class AbstractTextBoundLineGraphicFactory extends AbstractLineGraphicFactory {

protected Editor editor;

protected final int containerHeight = 16; // Each line graphic region is only 16px tall
protected final int containerWidth = 16;

/**
* @param priority Priority dictating the order of graphics displayed in {@link RootLineGraphicFactory}.
* See {@link LineGraphicFactory} for constants.
*/
protected AbstractTextBoundLineGraphicFactory(int priority) {
super(priority);
}

@Override
public void install(@Nonnull Editor editor) {
this.editor = editor;
}

@Override
public void uninstall(@Nonnull Editor editor) {
this.editor = null;
}

@Override
public void apply(@Nonnull LineContainer container, int paragraph) {

// To keep the ordering of the line graphic factory priority we need to add the stack pane now
// since the rest of the work is done async below. We want this to have zero width so that it doesn't
// shit the editor around when the content becomes active/inactive.
StackPane stack = new StackPane();
stack.setManaged(false);
stack.setPrefWidth(0);
stack.setMouseTransparent(true);
container.addHorizontal(stack);

FxThreadUtil.delayedRun(0, () -> {
stack.setPrefSize(containerHeight, containerHeight);
stack.setAlignment(Pos.CENTER_LEFT);
SceneUtils.getParentOfTypeLater(container, VirtualizedScrollPaneWrapper.class).whenComplete((parentScroll, error) -> {
ObservableValue<? extends Number> translateX;
if (parentScroll != null) {
translateX = Bindings.add(container.widthProperty().subtract(containerHeight), parentScroll.horizontalScrollProperty().negate());
} else {
// Should never happen since the 'VirtualizedScrollPaneWrapper' is mandated internally by 'Editor'.
translateX = container.widthProperty().subtract(containerHeight);
}
stack.translateXProperty().bind(translateX);
});

apply(stack, paragraph);
});
}

/**
* Apply the line graphic to the given pane,
* the pane is always bound to the beginning of the line.
* @param pane The pane to apply the graphic to.
* @param paragraph The paragraph index.
*/
protected abstract void apply(@NonNull StackPane pane, int paragraph);
}
Loading

0 comments on commit cb5aaab

Please sign in to comment.