Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
77 changes: 76 additions & 1 deletion src/org/openlcb/cdi/swing/CdiPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,9 @@ private void runUpdateComplete() {
private final List<EntryPane> allEntries = new ArrayList<>();
private final Map<String, EntryPane> entriesByKey = new HashMap<>();
private final Map<String, JTabbedPane> tabsByKey = new HashMap<>();
private final Map<String, CollapsiblePanel> segmentTitlesByKey = new HashMap<>();
private final Map<String, GroupPane> groupTitlesByKey = new HashMap<>();
private final Map<String, CollapsiblePanel> collapsibleGroupTitlesByKey = new HashMap<>();
// These need to be executed when closing the window.
private final ArrayList<Runnable> cleanupTasks = new ArrayList<>();
// Deferred callbacks that came during the rendering of the window.
Expand Down Expand Up @@ -983,6 +986,43 @@ private void performTabColorRefresh(long requestTick) {
boolean isDirty = false;
boolean isInvalid = false;

private void colorTitle(String key, boolean dirty, boolean invalid) {
Color color = invalid ? COLOR_INVALID : dirty ? COLOR_EDITED : null;
CollapsiblePanel segment = segmentTitlesByKey.get(key);
if (segment != null) segment.setTitleBackground(color);
CollapsiblePanel collapsibleGroup = collapsibleGroupTitlesByKey.get(key);
if (collapsibleGroup != null) collapsibleGroup.setTitleBackground(color);
GroupPane group = groupTitlesByKey.get(key);
if (group != null && group.titleBorder != null) {
group.titleBorder.setTitleBackground(color);
group.repaint();
}
}

@Override
public void visitSegment(ConfigRepresentation.SegmentEntry e) {
boolean oldDirty = isDirty;
boolean oldInvalid = isInvalid;
isDirty = false;
isInvalid = false;
super.visitSegment(e);
colorTitle(e.key, isDirty, isInvalid);
isDirty |= oldDirty;
isInvalid |= oldInvalid;
}

@Override
public void visitGroup(ConfigRepresentation.GroupEntry e) {
boolean oldDirty = isDirty;
boolean oldInvalid = isInvalid;
isDirty = false;
isInvalid = false;
super.visitGroup(e);
colorTitle(e.key, isDirty, isInvalid);
isDirty |= oldDirty;
isInvalid |= oldInvalid;
}

@Override
public void visitGroupRep(ConfigRepresentation.GroupRep e) {
boolean oldDirty = isDirty;
Expand Down Expand Up @@ -1085,6 +1125,7 @@ public void visitSegment(ConfigRepresentation.SegmentEntry e) {

String name = "Segment" + (e.getName() != null ? (": " + e.getName()) : "");
util.CollapsiblePanel cPanel = new util.CollapsiblePanel(name, currentPane);
segmentTitlesByKey.put(e.key, cPanel);
segmentPanels.add(cPanel);
addNavigationActions(cPanel);
// cPanel.setBorder(BorderFactory.createLineBorder(java.awt.Color.RED)); //debugging
Expand All @@ -1103,6 +1144,7 @@ public void visitGroup(ConfigRepresentation.GroupEntry e) {
JTabbedPane oldTabbed = currentTabbedPane;

GroupPane groupPane = new GroupPane(e);
groupTitlesByKey.put(e.key, groupPane);
currentPane = groupPane;
if (e.group.getReplication() > 1) {
currentTabbedPane = new JTabbedPane();
Expand Down Expand Up @@ -1132,6 +1174,7 @@ public void visitGroup(ConfigRepresentation.GroupEntry e) {
if (oldPane instanceof SegmentPane || e.isHideable()) { // we only make toplevel groups collapsible unless hint requests
groupPane.setBorder(null);
CollapsiblePanel cPanel = new CollapsiblePanel(groupPane.getName(), groupPane);
collapsibleGroupTitlesByKey.put(e.key, cPanel);
// cPanel.setBorder(BorderFactory.createLineBorder(java.awt.Color.RED)); //debugging
cPanel.setAlignmentY(Component.TOP_ALIGNMENT);
cPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
Expand Down Expand Up @@ -1892,13 +1935,15 @@ void attachParent(JPanel parentPane, JTextComponent output) {
public class GroupPane extends JPanel {
private final ConfigRepresentation.GroupEntry entry;
private final CdiRep.Item item;
private final CdiTitleBorder titleBorder;
GroupPane(ConfigRepresentation.GroupEntry e) {
entry = e;
item = e.getCdiItem();
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setAlignmentX(Component.LEFT_ALIGNMENT);
String name = (item.getName() != null ? (item.getName()) : "Group");
setBorder(BorderFactory.createTitledBorder(name));
titleBorder = new CdiTitleBorder(name);
setBorder(titleBorder);
setName(name);

createDescriptionPane(this, item.getDescription());
Expand All @@ -1912,6 +1957,36 @@ public class GroupPane extends JPanel {
}
}

/** Titled border that can fill the title area to match repeated-group tabs. */
private static class CdiTitleBorder extends javax.swing.border.TitledBorder {
private Color titleBackground;

CdiTitleBorder(String title) {
super(title);
}

void setTitleBackground(Color color) {
titleBackground = color;
}

@Override
public void paintBorder(Component component, java.awt.Graphics graphics,
int x, int y, int width, int height) {
if (titleBackground != null) {
java.awt.Graphics2D g = (java.awt.Graphics2D) graphics.create();
Font font = getTitleFont() != null ? getTitleFont() : component.getFont();
g.setFont(font);
java.awt.FontMetrics metrics = g.getFontMetrics();
int titleX = x + 9;
int titleY = y + 1;
g.setColor(titleBackground);
g.fillRect(titleX, titleY, metrics.stringWidth(getTitle()) + 8, metrics.getHeight());
g.dispose();
}
super.paintBorder(component, graphics, x, y, width, height);
}
}

Font countAreaFont; // font for the character count fields
{
Font existingFont = UIManager.getFont("TextArea.font");
Expand Down
13 changes: 13 additions & 0 deletions src/util/CollapsiblePanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class CollapsiblePanel extends JPanel {
HeaderPanel headerPanel_;
// The width given by the parent which we should try to set as a maximum width for the layout.
private int setWidth_ = Integer.MAX_VALUE;
private Color titleBackground;

private class HeaderPanel extends JPanel implements MouseListener, FocusListener, KeyListener {
/** Comment for <code>serialVersionUID</code>. */
Expand Down Expand Up @@ -85,6 +86,12 @@ protected void paintComponent(Graphics g) {
float height = lm.getAscent() + lm.getDescent();
float x = OFFSET;
float y = (h + height) / 2 - lm.getDescent();
if (titleBackground != null) {
g2.setColor(titleBackground);
g2.fillRect((int) x - 3, (int) (y - lm.getAscent()),
(int) font.getStringBounds(text_, frc).getWidth() + 6, (int) height);
}
g2.setColor(UIManager.getColor("Label.foreground"));
g2.drawString(text_, x, y);
}

Expand Down Expand Up @@ -162,6 +169,12 @@ public JPanel getHeader() {
return headerPanel_;
}

/** Sets the background color behind the panel title, or null for no fill. */
public void setTitleBackground(Color color) {
titleBackground = color;
headerPanel_.repaint();
}

public void toggleSelection() {
selected = !selected;
contentPanel_.setVisible(selected);
Expand Down
Loading