Skip to content

Commit

Permalink
feature(flamegraph): Allow to override some colors of the dimmed colo…
Browse files Browse the repository at this point in the history
…r provider

Refs: #80
  • Loading branch information
bric3 committed Jul 15, 2022
1 parent 1225990 commit e297d41
Showing 1 changed file with 97 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import io.github.bric3.fireplace.core.ui.DarkLightColor;

import java.awt.*;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

Expand All @@ -47,40 +48,77 @@
import static io.github.bric3.fireplace.flamegraph.FrameRenderingFlags.isHoveredSibling;
import static io.github.bric3.fireplace.flamegraph.FrameRenderingFlags.isMinimapMode;

/**
* Frame color provider that supports frame dimming and hovering.
*
* <p>
* This frame color provider is responsible for computing the color of a frame.
* It uses the actual frame and passes it to a basic <em>color function</em>
* that will apply the actual base background color to the frame.
* </p>
*
* <p>
* Then this base color can be altered or changed depending on the frame's
* flags.
* </p>
*
* @param <T> The actual type of frame.
*/
public class DimmingFrameColorProvider<T> implements FrameColorProvider<T> {
public static final Color DIMMED_TEXT = new DarkLightColor(
public static final Color DIMMED_TEXT_COLOR = new DarkLightColor(
Colors.rgba(28, 43, 52, 0.68f),
Colors.rgba(255, 255, 255, 0.51f)
);

public static final Color HOVERED_NODE = new DarkLightColor(
public static final Color HOVERED_BACKGROUND_COLOR = new DarkLightColor(
new Color(0xFFE0C268, true),
new Color(0xD0E0C268, true)
);

public static final Color ROOT_NODE = new DarkLightColor(
public static final Color ROOT_BACKGROUND_COLOR = new DarkLightColor(
new Color(0xFFEAF6FC),
new Color(0xFF091222)
);
private final Function<FrameBox<T>, Color> baseColorFunction;

/**
* Single instance to avoid too many allocations, only for the main canvas.
*/
private final ColorModel reusedColorModelForMainCanvas = new ColorModel(null, null);

/**
* Single instance to avoid too many allocations, only for the minimap.
* Since the minimap generation happens on a different thread, it is necessary
* to have a separate instance.
*/
private final ColorModel reusedColorModelForMinimap = new ColorModel(null, null);

private final ConcurrentHashMap<Color, Color> dimmedColorCache = new ConcurrentHashMap<>();

private Color rootBackGroundColor = ROOT_BACKGROUND_COLOR;
private Color dimmedTextColor = DIMMED_TEXT_COLOR;
private Color hoveredBackgroundColor = HOVERED_BACKGROUND_COLOR;

/**
* Builds a basic frame color provider.
*
* @param baseColorFunction The color function that provides the frame's color.
* @see #withRootBackgroundColor(Color)
* @see #withDimmedTextColor(Color)
* @see #withHoveredBackgroundColor(Color)
*/
public DimmingFrameColorProvider(Function<FrameBox<T>, Color> baseColorFunction) {
this.baseColorFunction = baseColorFunction;
}


@Override
public ColorModel getColors(FrameBox<T> frame, int flags) {
Color backgroundColor;
Color foreground;

var rootNode = frame.isRoot();
if (rootNode) {
backgroundColor = ROOT_NODE;
backgroundColor = rootBackGroundColor;
} else {
backgroundColor = baseColorFunction.apply(frame);
}
Expand All @@ -91,14 +129,19 @@ public ColorModel getColors(FrameBox<T> frame, int flags) {
}

if (!rootNode && shouldDim(flags)) {
backgroundColor = cachedDim(backgroundColor);
foreground = DIMMED_TEXT;
backgroundColor = dimmedBackground(backgroundColor);
foreground = dimmedTextColor;
} else {
foreground = Colors.foregroundColor(backgroundColor);
}

if (isHovered(flags) || isHoveredSibling(flags)) {
backgroundColor = Colors.blend(backgroundColor, HOVERED_NODE);
if (isHovered(flags)) {
backgroundColor = hoverBackground(backgroundColor);
foreground = Colors.foregroundColor(backgroundColor);
}

if (isHoveredSibling(flags)) {
backgroundColor = hoverSiblingBackground(backgroundColor);
foreground = Colors.foregroundColor(backgroundColor);
}

Expand All @@ -108,6 +151,36 @@ public ColorModel getColors(FrameBox<T> frame, int flags) {
);
}

/**
* Compute the background color for a hovered frame.
*
* @param backgroundColor The background color of the frame to alter.
* @return The hovered background color.
*/
private Color hoverBackground(Color backgroundColor) {
return Colors.blend(backgroundColor, hoveredBackgroundColor);
}

/**
* Compute the background color for a hovered sibling frame.
*
* @param backgroundColor The background color of the frame to alter.
* @return The hovered background color.
*/
private Color hoverSiblingBackground(Color backgroundColor) {
return Colors.blend(backgroundColor, hoveredBackgroundColor);
}

/**
* Dims the background color.
*
* @param backgroundColor The background color to dim.
* @return The dimmed color.
*/
protected Color dimmedBackground(Color backgroundColor) {
return cachedDim(backgroundColor);
}

/**
* Dim only if not highlighted or not focused
* <p>
Expand Down Expand Up @@ -137,4 +210,19 @@ private boolean shouldDim(int flags) {
private Color cachedDim(Color color) {
return dimmedColorCache.computeIfAbsent(color, Colors::dim);
}

public DimmingFrameColorProvider<T> withRootBackgroundColor(Color rootBackgroundColor) {
this.rootBackGroundColor = Objects.requireNonNull(rootBackgroundColor);
return this;
}

public DimmingFrameColorProvider<T> withDimmedTextColor(Color dimmedTextColor) {
this.dimmedTextColor = Objects.requireNonNull(dimmedTextColor);
return this;
}

public DimmingFrameColorProvider<T> withHoveredBackgroundColor(Color hoveredBackgroundColor) {
this.hoveredBackgroundColor = Objects.requireNonNull(hoveredBackgroundColor);
return this;
}
}

0 comments on commit e297d41

Please sign in to comment.