DevoxxGenieIDEAPlugin icon indicating copy to clipboard operation
DevoxxGenieIDEAPlugin copied to clipboard

The expandable "Using x References" panel is collapsed by default but still adds height for used files

Open stephanj opened this issue 1 year ago • 1 comments

When files are attached to window context the ExpandablePanel still calculates extra height to show the attached files but because its collapsed by default we see a lot of empty space under the prompt response.

stephanj avatar Aug 21 '24 08:08 stephanj

Possible solution

package com.devoxx.genie.ui.component;

import com.devoxx.genie.model.request.ChatMessageContext;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.components.JBPanel;
import com.intellij.ui.components.JBScrollPane;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;
import java.util.List;
import java.util.Objects;

import static com.devoxx.genie.action.AddSnippetAction.ORIGINAL_FILE_KEY;
import static com.devoxx.genie.ui.util.DevoxxGenieColorsUtil.PROMPT_BG_COLOR;
import static com.devoxx.genie.ui.util.DevoxxGenieIconsUtil.ArrowExpand;
import static com.devoxx.genie.ui.util.DevoxxGenieIconsUtil.ArrowExpanded;

public class ExpandablePanel extends JBPanel<ExpandablePanel> {

    private boolean isExpanded = false;
    private final JButton toggleButton;
    private final JPanel contentPanel;
    private final int fileCount;

    public ExpandablePanel(ChatMessageContext chatMessageContext,
                           @NotNull List<VirtualFile> files) {
        setLayout(new BorderLayout());

        andTransparent();
        withBackground(PROMPT_BG_COLOR);
        withBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));

        fileCount = files.size();
        String referenceText = "Using " + fileCount + " reference" + (fileCount > 1 ? "s" : "");

        toggleButton = new JButton(referenceText, ArrowExpand);
        toggleButton.addActionListener(e ->  toggleContent());
        toggleButton.setHorizontalAlignment(SwingConstants.LEFT);
        toggleButton.setBorder(BorderFactory.createEmptyBorder());
        toggleButton.setOpaque(false);
        toggleButton.setContentAreaFilled(false);
        toggleButton.setBorderPainted(false);
        add(toggleButton, BorderLayout.NORTH);

        contentPanel = new JPanel();
        contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
        contentPanel.setBackground(PROMPT_BG_COLOR);

        for (VirtualFile file : files) {
            contentPanel.add(new FileEntryComponent(chatMessageContext.getProject(), file, null));
        }
        contentPanel.setVisible(isExpanded);

        JScrollPane scrollPane = new JBScrollPane(contentPanel);
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.setBorder(null);
        scrollPane.getViewport().setOpaque(false);
        scrollPane.setOpaque(false);

        add(scrollPane, BorderLayout.CENTER);

        // Set initial minimum size to just fit the toggle button
        updatePanelSize();
    }

    private void toggleContent() {
        isExpanded = !isExpanded;
        contentPanel.setVisible(isExpanded);
        toggleButton.setIcon(isExpanded ? ArrowExpanded : ArrowExpand);

        updatePanelSize();

//        contentPanel.getParent().revalidate();
//        contentPanel.getParent().repaint();

        Rectangle rectangle = SwingUtilities.calculateInnerArea(contentPanel, contentPanel.getBounds());
        contentPanel.scrollRectToVisible(rectangle);
    }

    private void updatePanelSize() {
        if (isExpanded) {
            // TODO This is a hack to make the panel expand to fit all the files and uses 30px per file as an estimate
            // TODO However depending on the IDEA zoom level, the actual height of the file entry component can vary
            setMinimumSize(new Dimension(0, Math.min(300, 30 * fileCount + toggleButton.getPreferredSize().height)));
        } else {
            setMinimumSize(new Dimension(0, toggleButton.getPreferredSize().height));
        }
        revalidate();
        repaint();
    }
}

stephanj avatar Aug 21 '24 12:08 stephanj

Fixed

stephanj avatar Jan 28 '25 09:01 stephanj