mirror of
https://github.com/carlrobertoh/ProxyAI.git
synced 2026-05-09 19:45:16 +00:00
Expand/Collapse logic for toolwindow editors
This commit is contained in:
parent
dea80fe8aa
commit
d8e5e18998
6 changed files with 86 additions and 31 deletions
|
|
@ -125,8 +125,7 @@ public abstract class BaseChatToolWindowTabPanel implements ChatToolWindowTabPan
|
|||
(!youUserManager.isAuthenticated() || !youUserManager.isSubscribed())) {
|
||||
scrollablePanel.add(new ResponsePanel().addContent(createYouCouponTextPane()));
|
||||
}
|
||||
scrollablePanel.repaint();
|
||||
scrollablePanel.revalidate();
|
||||
revalidateScrollablePanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -142,11 +141,7 @@ public abstract class BaseChatToolWindowTabPanel implements ChatToolWindowTabPan
|
|||
}
|
||||
|
||||
var messageWrapper = createNewMessageWrapper(message.getId());
|
||||
messageWrapper.add(new UserMessagePanel(
|
||||
project,
|
||||
message,
|
||||
message.getUserMessage() != null,
|
||||
this));
|
||||
messageWrapper.add(new UserMessagePanel(project, message, this));
|
||||
var responsePanel = new ResponsePanel()
|
||||
.withReloadAction(() -> reloadMessage(message, conversation))
|
||||
.withDeleteAction(() -> removeMessage(message.getId(), messageWrapper, conversation))
|
||||
|
|
@ -168,8 +163,7 @@ public abstract class BaseChatToolWindowTabPanel implements ChatToolWindowTabPan
|
|||
.filter(component -> component instanceof ResponsePanel)
|
||||
.findFirst().orElseThrow();
|
||||
((ChatMessageResponseBody) responsePanel.getContent()).clear();
|
||||
scrollablePanel.revalidate();
|
||||
scrollablePanel.repaint();
|
||||
revalidateScrollablePanel();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Couldn't delete the existing message component", e);
|
||||
} finally {
|
||||
|
|
@ -187,10 +181,14 @@ public abstract class BaseChatToolWindowTabPanel implements ChatToolWindowTabPan
|
|||
}
|
||||
}
|
||||
|
||||
protected void removeMessage(UUID messageId, JPanel messageWrapper, Conversation conversation) {
|
||||
scrollablePanel.remove(messageWrapper);
|
||||
private void revalidateScrollablePanel() {
|
||||
scrollablePanel.repaint();
|
||||
scrollablePanel.revalidate();
|
||||
}
|
||||
|
||||
protected void removeMessage(UUID messageId, JPanel messageWrapper, Conversation conversation) {
|
||||
scrollablePanel.remove(messageWrapper);
|
||||
revalidateScrollablePanel();
|
||||
|
||||
visibleMessagePanels.remove(messageId);
|
||||
conversation.removeMessage(messageId);
|
||||
|
|
@ -207,16 +205,14 @@ public abstract class BaseChatToolWindowTabPanel implements ChatToolWindowTabPan
|
|||
var messageWrapper = new JPanel();
|
||||
messageWrapper.setLayout(new BoxLayout(messageWrapper, BoxLayout.PAGE_AXIS));
|
||||
scrollablePanel.add(messageWrapper);
|
||||
scrollablePanel.repaint();
|
||||
scrollablePanel.revalidate();
|
||||
revalidateScrollablePanel();
|
||||
visibleMessagePanels.put(messageId, messageWrapper);
|
||||
return messageWrapper;
|
||||
}
|
||||
|
||||
protected void clearWindow() {
|
||||
scrollablePanel.removeAll();
|
||||
scrollablePanel.revalidate();
|
||||
scrollablePanel.repaint();
|
||||
revalidateScrollablePanel();
|
||||
}
|
||||
|
||||
private void call(
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
private final Project project;
|
||||
private final Disposable parentDisposable;
|
||||
private final StreamParser streamParser;
|
||||
private final boolean readOnly;
|
||||
private JPanel currentlyProcessedElement;
|
||||
private ResponseEditor currentlyProcessedEditor;
|
||||
private JTextPane currentlyProcessedTextPane;
|
||||
|
|
@ -65,10 +66,20 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
Color backgroundColor,
|
||||
boolean withGhostText,
|
||||
Disposable parentDisposable) {
|
||||
this(project, backgroundColor, withGhostText, false, parentDisposable);
|
||||
}
|
||||
|
||||
public ChatMessageResponseBody(
|
||||
Project project,
|
||||
Color backgroundColor,
|
||||
boolean withGhostText,
|
||||
boolean readOnly,
|
||||
Disposable parentDisposable) {
|
||||
super(new BorderLayout());
|
||||
this.project = project;
|
||||
this.parentDisposable = parentDisposable;
|
||||
this.streamParser = new StreamParser();
|
||||
this.readOnly = readOnly;
|
||||
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
|
||||
setBackground(backgroundColor);
|
||||
|
||||
|
|
@ -237,6 +248,8 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
project,
|
||||
code,
|
||||
markdownLanguage,
|
||||
readOnly,
|
||||
getPanelBackgroundColor(),
|
||||
parentDisposable);
|
||||
currentlyProcessedElement = new ResponseWrapper();
|
||||
|
||||
|
|
|
|||
|
|
@ -14,13 +14,19 @@ import javax.swing.JPanel;
|
|||
|
||||
public class UserMessagePanel extends JPanel {
|
||||
|
||||
public UserMessagePanel(Project project, Message message, boolean displayEditorMessage, Disposable parentDisposable) {
|
||||
public UserMessagePanel(Project project, Message message, Disposable parentDisposable) {
|
||||
super(new BorderLayout());
|
||||
setBorder(JBUI.Borders.compound(
|
||||
JBUI.Borders.customLine(JBColor.border(), 0, 0, 1, 0),
|
||||
JBUI.Borders.empty(12, 8, 8, 8)));
|
||||
add(createDisplayNameWrapper(), BorderLayout.NORTH);
|
||||
add(createUserMessageTextPane(project, message, displayEditorMessage, parentDisposable), BorderLayout.SOUTH);
|
||||
add(new ChatMessageResponseBody(
|
||||
project,
|
||||
UIUtil.getPanelBackground(),
|
||||
false,
|
||||
true,
|
||||
parentDisposable).withResponse(message.getPrompt()),
|
||||
BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
private JPanel createDisplayNameWrapper() {
|
||||
|
|
@ -30,12 +36,4 @@ public class UserMessagePanel extends JPanel {
|
|||
.setAllowAutoWrapping(true)
|
||||
.withFont(JBFont.label().asBold()));
|
||||
}
|
||||
|
||||
private JPanel createUserMessageTextPane(Project project, Message message, boolean displayEditorMessage, Disposable parentDisposable) {
|
||||
var prompt = message.getPrompt();
|
||||
if (displayEditorMessage && message.getUserMessage() != null) {
|
||||
prompt = message.getUserMessage();
|
||||
}
|
||||
return new ChatMessageResponseBody(project, UIUtil.getPanelBackground(), false, parentDisposable).withResponse(prompt);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.chat.editor;
|
||||
|
||||
import static ee.carlrobert.codegpt.util.file.FileUtils.findLanguageExtensionMapping;
|
||||
import static java.lang.String.format;
|
||||
|
||||
import com.intellij.icons.AllIcons.General;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.ActionGroup;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
|
|
@ -15,8 +17,10 @@ import com.intellij.openapi.editor.impl.ContextMenuPopupHandler;
|
|||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.components.ActionLink;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import ee.carlrobert.codegpt.CodeGPTBundle;
|
||||
import ee.carlrobert.codegpt.actions.toolwindow.ReplaceCodeInMainEditorAction;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.components.IconActionButton;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.editor.actions.CopyAction;
|
||||
|
|
@ -26,6 +30,7 @@ import ee.carlrobert.codegpt.toolwindow.chat.editor.actions.NewFileAction;
|
|||
import ee.carlrobert.codegpt.toolwindow.chat.editor.actions.ReplaceSelectionAction;
|
||||
import ee.carlrobert.codegpt.util.EditorUtils;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.FlowLayout;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.JPanel;
|
||||
|
|
@ -40,6 +45,8 @@ public class ResponseEditor extends JPanel implements Disposable {
|
|||
Project project,
|
||||
String code,
|
||||
String markdownLanguage,
|
||||
boolean readOnly,
|
||||
Color backgroundColor,
|
||||
Disposable disposableParent) {
|
||||
super(new BorderLayout());
|
||||
|
||||
|
|
@ -60,6 +67,10 @@ public class ResponseEditor extends JPanel implements Disposable {
|
|||
}
|
||||
|
||||
var editorEx = ((EditorEx) editor);
|
||||
if (readOnly) {
|
||||
editorEx.setOneLineMode(true);
|
||||
editorEx.setHorizontalScrollbarVisible(false);
|
||||
}
|
||||
editorEx.installPopupHandler(new ContextMenuPopupHandler.Simple(group));
|
||||
editorEx.setColorsScheme(EditorColorsManager.getInstance().getSchemeForCurrentUITheme());
|
||||
|
||||
|
|
@ -72,8 +83,9 @@ public class ResponseEditor extends JPanel implements Disposable {
|
|||
settings.setLineMarkerAreaShown(false);
|
||||
settings.setGutterIconsShown(false);
|
||||
|
||||
add(createHeaderComponent(), BorderLayout.NORTH);
|
||||
add(editor.getComponent(), BorderLayout.SOUTH);
|
||||
add(createHeaderComponent(readOnly), BorderLayout.NORTH);
|
||||
add(editor.getComponent(), BorderLayout.CENTER);
|
||||
add(createFooterComponent(readOnly ? getBackground() : backgroundColor), BorderLayout.SOUTH);
|
||||
|
||||
Disposer.register(disposableParent, this);
|
||||
}
|
||||
|
|
@ -87,16 +99,50 @@ public class ResponseEditor extends JPanel implements Disposable {
|
|||
return editor;
|
||||
}
|
||||
|
||||
private JPanel createHeaderComponent() {
|
||||
private JPanel createHeaderComponent(boolean readOnly) {
|
||||
var headerComponent = new JPanel(new BorderLayout());
|
||||
headerComponent.setBorder(JBUI.Borders.compound(
|
||||
JBUI.Borders.customLine(JBColor.border(), 1, 1, 1, 1),
|
||||
JBUI.Borders.empty(8)));
|
||||
JBUI.Borders.empty(4, 8)));
|
||||
headerComponent.add(new JBLabel(language), BorderLayout.LINE_START);
|
||||
headerComponent.add(createHeaderActions(), BorderLayout.LINE_END);
|
||||
if (!readOnly) {
|
||||
headerComponent.add(createHeaderActions(), BorderLayout.LINE_END);
|
||||
}
|
||||
return headerComponent;
|
||||
}
|
||||
|
||||
private String getLinkText(boolean expanded) {
|
||||
return expanded ?
|
||||
format(
|
||||
CodeGPTBundle.get("toolwindow.chat.editor.action.expand"),
|
||||
((EditorEx) editor).getDocument().getLineCount() - 1) :
|
||||
CodeGPTBundle.get("toolwindow.chat.editor.action.collapse");
|
||||
}
|
||||
|
||||
private JPanel createFooterComponent(Color backgroundColor) {
|
||||
var editorEx = ((EditorEx) editor);
|
||||
var linkText = getLinkText(editorEx.isOneLineMode());
|
||||
var expandLink = new ActionLink(
|
||||
linkText,
|
||||
event -> {
|
||||
var oneLineMode = editorEx.isOneLineMode();
|
||||
var source = (ActionLink) event.getSource();
|
||||
source.setText(getLinkText(!oneLineMode));
|
||||
source.setIcon(oneLineMode ? General.ArrowUp : General.ArrowDown, true);
|
||||
|
||||
editorEx.setOneLineMode(!oneLineMode);
|
||||
editorEx.setHorizontalScrollbarVisible(oneLineMode);
|
||||
editorEx.getContentComponent().revalidate();
|
||||
editorEx.getContentComponent().repaint();
|
||||
});
|
||||
expandLink.setIcon(editorEx.isOneLineMode() ? General.ArrowDown : General.ArrowUp, true);
|
||||
|
||||
var panel = new JPanel(new FlowLayout(FlowLayout.CENTER));
|
||||
panel.setBackground(backgroundColor);
|
||||
panel.add(expandLink);
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JPanel createHeaderActions() {
|
||||
var wrapper = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
|
||||
wrapper.add(new IconActionButton(new DiffAction(editor)));
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ public class StandardChatToolWindowTabPanel extends BaseChatToolWindowTabPanel {
|
|||
}
|
||||
|
||||
var messageWrapper = createNewMessageWrapper(message.getId());
|
||||
messageWrapper.add(new UserMessagePanel(project, message, false, this));
|
||||
messageWrapper.add(new UserMessagePanel(project, message, this));
|
||||
messageWrapper.add(new ResponsePanel()
|
||||
.withReloadAction(() -> reloadMessage(message, conversation))
|
||||
.withDeleteAction(() -> removeMessage(message.getId(), messageWrapper, conversation))
|
||||
|
|
|
|||
|
|
@ -99,6 +99,8 @@ toolwindow.chat.editor.action.newFile.title=New File
|
|||
toolwindow.chat.editor.action.newFile.description=Create new file from generated code
|
||||
toolwindow.chat.editor.action.replaceSelection.title=Replace Selection
|
||||
toolwindow.chat.editor.action.replaceSelection.description=Replace main editor selected code
|
||||
toolwindow.chat.editor.action.expand=Show More (+%s rows)
|
||||
toolwindow.chat.editor.action.collapse=Show Less
|
||||
toolwindow.chat.response.action.reloadResponse.text=Reload Response
|
||||
toolwindow.chat.response.action.reloadResponse.description=Reload response description
|
||||
toolwindow.chat.response.action.deleteResponse.text=Delete Response
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue