mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GP-1981 - Checkpoint - Function Call Graph
This commit is contained in:
parent
16e32317f0
commit
60b1ae8b44
15 changed files with 276 additions and 41 deletions
|
@ -5,6 +5,7 @@
|
|||
##MODULE IP: Tango Icons - Public Domain
|
||||
Module.manifest||GHIDRA||||END|
|
||||
data/ExtensionPoint.manifest||GHIDRA||||END|
|
||||
data/functiongraph.theme.properties||GHIDRA||||END|
|
||||
src/main/help/help/TOC_Source.xml||GHIDRA||||END|
|
||||
src/main/help/help/shared/arrow.gif||GHIDRA||reviewed||END|
|
||||
src/main/help/help/shared/close16.gif||GHIDRA||reviewed||END|
|
||||
|
|
|
@ -24,12 +24,23 @@ color.bg.functiongraph.paint.icon = rgb(189, 221, 252) // gentle pale blue
|
|||
[Dark Defaults]
|
||||
|
||||
|
||||
color.bg.functiongraph.vertex.group = rgb(226, 222, 179) // TODO confirm value
|
||||
// color.bg.functiongraph = color.bg
|
||||
|
||||
// color.fg.label.picked = color.fg
|
||||
// color.fg.label.non-picked = color.fg.disabled
|
||||
|
||||
color.bg.functiongraph.vertex.group = rgb(226, 222, 179) // TODO confirm value
|
||||
// color.bg.functiongraph.vertex.entry = color.palette.lightgreen
|
||||
// color.bg.functiongraph.vertex.exit = color.palette.lightred
|
||||
// color.bg.functiongraph.vertex.picked = color.palette.yellow
|
||||
|
||||
// color.bg.functiongraph.edge.fall-through = color.flowtype.fall-through
|
||||
color.bg.functiongraph.edge.fall-through.highlight = rgb(165, 76, 80)
|
||||
// color.bg.functiongraph.edge.jump.conditional = color.flowtype.jump.conditional
|
||||
color.bg.functiongraph.edge.jump.conditional.highlight = rgb(95, 160, 196)
|
||||
// color.bg.functiongraph.edge.jump.unconditional = color.flowtype.jump.unconditional
|
||||
color.bg.functiongraph.edge.jump.unconditional.highlight = rgb(140, 162, 88)
|
||||
|
||||
|
||||
// TODO dark version color.bg.functiongraph.paint.icon =
|
||||
// TODO dark version color.bg.functiongraph.paint.icon = // TODO
|
||||
|
|
@ -59,8 +59,7 @@ import ghidra.program.model.symbol.Symbol;
|
|||
import ghidra.program.model.symbol.SymbolTable;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.util.HTMLUtilities;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.*;
|
||||
import resources.ResourceManager;
|
||||
|
||||
public class ListingGraphComponentPanel extends AbstractGraphComponentPanel {
|
||||
|
@ -561,11 +560,7 @@ public class ListingGraphComponentPanel extends AbstractGraphComponentPanel {
|
|||
private Color getToolTipColorForEdge(FGEdge edge) {
|
||||
FunctionGraphOptions options = controller.getFunctionGraphOptions();
|
||||
Color c = options.getColor(edge.getFlowType());
|
||||
return withAlpha(c, 125);
|
||||
}
|
||||
|
||||
private Color withAlpha(Color c, int alpha) {
|
||||
return new Color(c.getRed(), c.getGreen(), c.getBlue(), 125);
|
||||
return ColorUtils.withAlpha(c, 125);
|
||||
}
|
||||
|
||||
private Address getPreviewAddress(boolean forward) {
|
||||
|
|
|
@ -1,3 +1,25 @@
|
|||
[Defaults]
|
||||
|
||||
color.fcg.satellite.edge = rgba(0,0,0,0.1)
|
||||
color.bg.fcg.vertex.default = rgb(110, 197, 174) // chill green
|
||||
color.bg.fcg.vertex.toobig = color.palette.lightGray
|
||||
|
||||
color.bg.fcg.edge.primary.direct = rgb(143, 197, 143) // lightGreen
|
||||
color.bg.fcg.edge.primary.indirect = rgb(233, 233, 233) // lightGray
|
||||
|
||||
// the satellite gets too cluttered, so wash out the edges
|
||||
color.bg.fcg.edge.satellite.direct = rgba(0,0,0,0.1) // 'washed out black'
|
||||
color.bg.fcg.edge.satellite.indirect = rgba(125, 125, 125, 25) // 'washed out gray'
|
||||
|
||||
|
||||
[Dark Defaults]
|
||||
|
||||
// TODO dark colors
|
||||
// TODO color.bg.fcg.vertex.default = rgb(110, 197, 174) // chill green
|
||||
// TODO color.bg.fcg.vertex.toobig = color.palette.lightGray
|
||||
|
||||
// TODO color.bg.fcg.edge.primary.direct = rgb(143, 197, 143) // lightGreen
|
||||
// TODO color.bg.fcg.edge.primary.indirect = rgb(233, 233, 233) // lightGray
|
||||
|
||||
// the satellite gets too cluttered, so wash out the edges
|
||||
// TODO color.bg.fcg.edge.satellite.direct = rgba(0,0,0,0.1) // 'washed out black'
|
||||
// TODO color.bg.fcg.edge.satellite.indirect = rgba(125, 125, 125, 25) // 'washed out gray'
|
|
@ -26,6 +26,8 @@ import javax.swing.*;
|
|||
import javax.swing.border.Border;
|
||||
import javax.swing.border.LineBorder;
|
||||
|
||||
import docking.theme.GColor;
|
||||
import docking.theme.GThemeDefaults.Colors.Palette;
|
||||
import docking.widgets.EmptyBorderButton;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import ghidra.graph.viewer.vertex.AbstractVisualVertex;
|
||||
|
@ -41,9 +43,10 @@ import resources.ResourceManager;
|
|||
*/
|
||||
public class FcgVertex extends AbstractVisualVertex implements VertexShapeProvider {
|
||||
|
||||
// TODO to be made an option in an upcoming ticket
|
||||
public static final Color DEFAULT_VERTEX_SHAPE_COLOR = new Color(110, 197, 174);
|
||||
private static final Color TOO_BIG_VERTEX_SHAPE_COLOR = Color.LIGHT_GRAY;
|
||||
//@formatter:off
|
||||
public static final Color DEFAULT_VERTEX_SHAPE_COLOR = new GColor("color.bg.fcg.vertex.default");
|
||||
private static final Color TOO_BIG_VERTEX_SHAPE_COLOR = new GColor("color.bg.fcg.vertex.toobig ");
|
||||
//@formatter:on
|
||||
|
||||
public static final Icon NOT_ALLOWED_ICON = Icons.ERROR_ICON;
|
||||
private static final Icon EXPAND_ICON =
|
||||
|
@ -312,8 +315,8 @@ public class FcgVertex extends AbstractVisualVertex implements VertexShapeProvid
|
|||
private void addToggleButtons() {
|
||||
|
||||
// hide the button background
|
||||
toggleInsButton.setBackground(new Color(255, 255, 255, 0));
|
||||
toggleOutsButton.setBackground(new Color(255, 255, 255, 0));
|
||||
toggleInsButton.setBackground(Palette.NO_COLOR);
|
||||
toggleOutsButton.setBackground(Palette.NO_COLOR);
|
||||
|
||||
Rectangle parentBounds = vertexImageLabel.getBounds();
|
||||
Dimension size = toggleInsButton.getPreferredSize();
|
||||
|
|
|
@ -21,13 +21,13 @@ import java.awt.Paint;
|
|||
import com.google.common.base.Function;
|
||||
|
||||
import functioncalls.graph.FcgEdge;
|
||||
import ghidra.util.ColorUtils;
|
||||
|
||||
/**
|
||||
* Generates colors for a given {@link FcgEdge}
|
||||
*/
|
||||
public class FcgEdgePaintTransformer implements Function<FcgEdge, Paint> {
|
||||
|
||||
// private static final Paint LESS_IMPORTANT_COLOR = new Color(125, 125, 125, 75);
|
||||
private Color directColor;
|
||||
private Color indirectColor;
|
||||
|
||||
|
@ -46,7 +46,7 @@ public class FcgEdgePaintTransformer implements Function<FcgEdge, Paint> {
|
|||
alphad[0] = c;
|
||||
for (int i = 1; i < 10; i++) {
|
||||
double newAlpha = 255 - (i * 25.5);
|
||||
alphad[i] = new Color(c.getRed(), c.getGreen(), c.getBlue(), (int) newAlpha);
|
||||
alphad[i] = ColorUtils.withAlpha(c, (int) newAlpha);
|
||||
}
|
||||
return alphad;
|
||||
}
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
*/
|
||||
package functioncalls.graph.view;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import docking.theme.GColor;
|
||||
import edu.uci.ics.jung.visualization.RenderContext;
|
||||
import functioncalls.graph.*;
|
||||
|
@ -38,19 +36,14 @@ public class FcgComponent extends GraphComponent<FcgVertex, FcgEdge, FunctionCal
|
|||
private FcgVertexPaintTransformer vertexPaintTransformer =
|
||||
new FcgVertexPaintTransformer(FcgVertex.DEFAULT_VERTEX_SHAPE_COLOR);
|
||||
|
||||
private Color lightGreen = new Color(143, 197, 143);
|
||||
private Color lightGray = new Color(233, 233, 233);
|
||||
|
||||
// the satellite gets too cluttered, so wash out the edges
|
||||
private Color washedOutBlack = new GColor("color.fcg.satellite.edge");
|
||||
|
||||
private FcgEdgePaintTransformer edgePaintTransformer =
|
||||
new FcgEdgePaintTransformer(lightGreen, lightGray);
|
||||
new FcgEdgePaintTransformer(new GColor("color.bg.fcg.edge.primary.direct"),
|
||||
new GColor("color.bg.fcg.edge.primary.indirect"));
|
||||
private FcgEdgePaintTransformer satelliteEdgePaintTransformer =
|
||||
new FcgEdgePaintTransformer(washedOutBlack, new Color(125, 125, 125, 25));
|
||||
new FcgEdgePaintTransformer(new GColor("color.bg.fcg.edge.satellite.direct"),
|
||||
new GColor("color.bg.fcg.edge.satellite.indirect"));
|
||||
|
||||
FcgComponent(FunctionCallGraph g) {
|
||||
|
||||
setGraph(g);
|
||||
build();
|
||||
}
|
||||
|
@ -75,7 +68,6 @@ public class FcgComponent extends GraphComponent<FcgVertex, FcgEdge, FunctionCal
|
|||
renderContext.setEdgeDrawPaintTransformer(edgePaintTransformer);
|
||||
renderContext.setArrowFillPaintTransformer(edgePaintTransformer);
|
||||
renderContext.setArrowDrawPaintTransformer(edgePaintTransformer);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
[Defaults]
|
||||
|
||||
color.palette.nocolor = rgba(255,255,255,0)
|
||||
|
||||
color.palette.black = black
|
||||
color.palette.cyan = cyan
|
||||
color.palette.lightGray = rgb(192, 192, 192)
|
||||
color.palette.lightgreen = rgb(127, 255, 127)
|
||||
color.palette.lightred = rgb(255, 127, 127)
|
||||
color.palette.red = red
|
||||
|
|
|
@ -21,11 +21,20 @@ import java.awt.geom.AffineTransform;
|
|||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.ColorModel;
|
||||
|
||||
public class GColor extends Color implements Refreshable {
|
||||
import ghidra.util.datastruct.WeakDataStructureFactory;
|
||||
import ghidra.util.datastruct.WeakSet;
|
||||
|
||||
public class GColor extends Color implements Refreshable {
|
||||
private static WeakSet<GColor> inUseColors = WeakDataStructureFactory.createCopyOnReadWeakSet();
|
||||
private String id;
|
||||
private Color delegate;
|
||||
|
||||
public static void refreshAll() {
|
||||
for (GColor gcolor : inUseColors) {
|
||||
gcolor.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public GColor(String id) {
|
||||
super(0x808080);
|
||||
this.id = id;
|
||||
|
@ -33,6 +42,7 @@ public class GColor extends Color implements Refreshable {
|
|||
if (delegate == null) {
|
||||
delegate = Color.gray;
|
||||
}
|
||||
inUseColors.add(this);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
|
|
|
@ -55,6 +55,8 @@ public class GThemeDefaults {
|
|||
* Generic palette colors, using color names, that may be changed along with the theme
|
||||
*/
|
||||
public static class Palette {
|
||||
public static final Color NO_COLOR = new GColor("color.palette.nocolor");
|
||||
|
||||
public static final Color BLACK = new GColor("color.palette.black");
|
||||
public static final Color CYAN = new GColor("color.palette.cyan");
|
||||
public static final Color RED = new GColor("color.palette.red");
|
||||
|
|
|
@ -32,7 +32,7 @@ import ghidra.util.filechooser.GhidraFileFilter;
|
|||
public class GThemeDialog extends DialogComponentProvider {
|
||||
|
||||
public GThemeDialog() {
|
||||
super("Theme Dialog");
|
||||
super("Theme Dialog", false);
|
||||
addWorkPanel(createMainPanel());
|
||||
addOKButton();
|
||||
addCancelButton();
|
||||
|
@ -80,6 +80,9 @@ public class GThemeDialog extends DialogComponentProvider {
|
|||
colorTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
GFilterTable<ColorValue> filterTable = new GFilterTable<>(colorTableModel);
|
||||
filterTable.getTable().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
filterTable.getTable()
|
||||
.setDefaultEditor(ColorValue.class,
|
||||
new ThemeColorEditor(Gui.getAllValues(), colorTableModel));
|
||||
return filterTable;
|
||||
}
|
||||
|
||||
|
|
|
@ -307,4 +307,10 @@ public class Gui {
|
|||
return map;
|
||||
}
|
||||
|
||||
public static void setColor(String id, Color color) {
|
||||
currentValues.addColor(new ColorValue(id, color));
|
||||
GColor.refreshAll();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package docking.theme;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.EventObject;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.BevelBorder;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.table.TableCellEditor;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.DockingWindowManager;
|
||||
import docking.options.editor.GhidraColorChooser;
|
||||
import docking.widgets.label.GDLabel;
|
||||
|
||||
public class ThemeColorEditor extends AbstractCellEditor implements TableCellEditor {
|
||||
private GhidraColorChooser colorChooser;
|
||||
private Color lastUserSelectedColor;
|
||||
private Color color;
|
||||
|
||||
private ColorDialogProvider dialog;
|
||||
private JTable table;
|
||||
private ColorValue colorValue;
|
||||
|
||||
private GThemeValueMap values;
|
||||
private ThemeColorTableModel model;
|
||||
|
||||
public ThemeColorEditor(GThemeValueMap values, ThemeColorTableModel model) {
|
||||
this.values = values;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTableCellEditorComponent(JTable theTable, Object value, boolean isSelected,
|
||||
int row, int column) {
|
||||
|
||||
this.table = theTable;
|
||||
colorValue = (ColorValue) value;
|
||||
|
||||
JLabel label = new GDLabel();
|
||||
label.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
|
||||
label.setText(colorValue.getId());
|
||||
|
||||
dialog = new ColorDialogProvider();
|
||||
dialog.setRememberSize(false);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
DockingWindowManager.showDialog(dialog);
|
||||
stopCellEditing();
|
||||
}
|
||||
});
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelCellEditing() {
|
||||
dialog.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCellEditorValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stopCellEditing() {
|
||||
ListSelectionModel columnSelectionModel = table.getColumnModel().getSelectionModel();
|
||||
columnSelectionModel.setValueIsAdjusting(true);
|
||||
int columnAnchor = columnSelectionModel.getAnchorSelectionIndex();
|
||||
int columnLead = columnSelectionModel.getLeadSelectionIndex();
|
||||
|
||||
if (color != null) {
|
||||
Gui.setColor(colorValue.getId(), color);
|
||||
model.refresh();
|
||||
}
|
||||
dialog.close();
|
||||
fireEditingStopped();
|
||||
|
||||
columnSelectionModel.setAnchorSelectionIndex(columnAnchor);
|
||||
columnSelectionModel.setLeadSelectionIndex(columnLead);
|
||||
columnSelectionModel.setValueIsAdjusting(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// only double-click edits
|
||||
@Override
|
||||
public boolean isCellEditable(EventObject anEvent) {
|
||||
if (anEvent instanceof MouseEvent) {
|
||||
return ((MouseEvent) anEvent).getClickCount() >= 2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Inner Classes
|
||||
//==================================================================================================
|
||||
|
||||
class ColorDialogProvider extends DialogComponentProvider {
|
||||
ColorDialogProvider() {
|
||||
super("Color Editor", true);
|
||||
|
||||
addWorkPanel(new ColorEditorPanel());
|
||||
addOKButton();
|
||||
addCancelButton();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void okCallback() {
|
||||
color = lastUserSelectedColor;
|
||||
close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cancelCallback() {
|
||||
color = null;
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
class ColorEditorPanel extends JPanel {
|
||||
|
||||
ColorEditorPanel() {
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
if (colorChooser == null) {
|
||||
colorChooser = new GhidraColorChooser();
|
||||
}
|
||||
|
||||
add(colorChooser, BorderLayout.CENTER);
|
||||
colorChooser.getSelectionModel().addChangeListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
lastUserSelectedColor = colorChooser.getColor();
|
||||
// This could be a ColorUIResource, but Options only support storing Color.
|
||||
lastUserSelectedColor =
|
||||
new Color(lastUserSelectedColor.getRed(), lastUserSelectedColor.getGreen(),
|
||||
lastUserSelectedColor.getBlue(), lastUserSelectedColor.getAlpha());
|
||||
}
|
||||
});
|
||||
colorChooser.setColor(colorValue.get(values));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,6 +38,11 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
|||
colors = Gui.getAllValues().getColors();
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
colors = Gui.getAllValues().getColors();
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Users";
|
||||
|
@ -48,6 +53,10 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
|||
return colors;
|
||||
}
|
||||
|
||||
public boolean isCellEditable(int row, int column) {
|
||||
return getColumnName(column).equals("Current Color");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TableColumnDescriptor<ColorValue> createTableColumnDescriptor() {
|
||||
TableColumnDescriptor<ColorValue> descriptor = new TableColumnDescriptor<>();
|
||||
|
@ -78,7 +87,7 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
|||
}
|
||||
}
|
||||
|
||||
class ValueColumn extends AbstractDynamicTableColumn<ColorValue, String, Object> {
|
||||
class ValueColumn extends AbstractDynamicTableColumn<ColorValue, ColorValue, Object> {
|
||||
private ThemeColorRenderer renderer = new ThemeColorRenderer(Gui.getAllValues());
|
||||
private GThemeValueMap valueMap;
|
||||
private String name;
|
||||
|
@ -95,18 +104,19 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getValue(ColorValue themeColor, Settings settings, Object data,
|
||||
public ColorValue getValue(ColorValue themeColor, Settings settings, Object data,
|
||||
ServiceProvider provider) throws IllegalArgumentException {
|
||||
return themeColor.getId();
|
||||
return themeColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GColumnRenderer<String> getColumnRenderer() {
|
||||
public GColumnRenderer<ColorValue> getColumnRenderer() {
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public Comparator<String> getComparator() {
|
||||
return (s1, s2) -> valueMap.getColor(s1).compareValue(valueMap.getColor(s2));
|
||||
public Comparator<ColorValue> getComparator() {
|
||||
return (v1, v2) -> valueMap.getColor(v1.getId())
|
||||
.compareValue(valueMap.getColor(v2.getId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -125,7 +135,7 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
|||
}
|
||||
}
|
||||
|
||||
private class ThemeColorRenderer extends AbstractGColumnRenderer<String> {
|
||||
private class ThemeColorRenderer extends AbstractGColumnRenderer<ColorValue> {
|
||||
|
||||
private GThemeValueMap valueMap;
|
||||
|
||||
|
@ -138,7 +148,7 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
|||
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
|
||||
|
||||
JLabel label = (JLabel) super.getTableCellRendererComponent(data);
|
||||
String id = (String) data.getValue();
|
||||
String id = ((ColorValue) data.getValue()).getId();
|
||||
|
||||
ColorValue colorValue = valueMap.getColor(id);
|
||||
Color color;
|
||||
|
@ -169,8 +179,9 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getFilterString(String id, Settings settings) {
|
||||
return id;
|
||||
public String getFilterString(ColorValue t, Settings settings) {
|
||||
return t.getId();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,6 +191,17 @@ public class ColorUtils {
|
|||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new color that is comprised of the given color's rgb value and the given alpha
|
||||
* value.
|
||||
* @param c the color
|
||||
* @param alpha the alpha
|
||||
* @return the new color
|
||||
*/
|
||||
public static Color withAlpha(Color c, int alpha) {
|
||||
return new Color(c.getRed(), c.getGreen(), c.getBlue(), alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* Blender of colors
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue