From 1c06a177e2a8ddb7b04bc32d2f8178fcfaa016c4 Mon Sep 17 00:00:00 2001 From: Stephan Janssen Date: Wed, 11 Dec 2024 09:01:38 +0100 Subject: [PATCH] Panel glowing --- .../ui/DevoxxGenieToolWindowContent.java | 16 ++++ .../border/AnimatedGlowingBorder.java | 83 +++++++++++++++++++ .../component/{ => border}/GlowingBorder.java | 2 +- .../ui/component/input/PromptInputArea.java | 47 ----------- .../genie/ui/panel/ActionButtonsPanel.java | 7 +- .../devoxx/genie/ui/panel/SubmitPanel.java | 12 ++- src/main/resources/application.properties | 2 +- 7 files changed, 116 insertions(+), 53 deletions(-) create mode 100644 src/main/java/com/devoxx/genie/ui/component/border/AnimatedGlowingBorder.java rename src/main/java/com/devoxx/genie/ui/component/{ => border}/GlowingBorder.java (96%) diff --git a/src/main/java/com/devoxx/genie/ui/DevoxxGenieToolWindowContent.java b/src/main/java/com/devoxx/genie/ui/DevoxxGenieToolWindowContent.java index 4bd1542c..408f3164 100644 --- a/src/main/java/com/devoxx/genie/ui/DevoxxGenieToolWindowContent.java +++ b/src/main/java/com/devoxx/genie/ui/DevoxxGenieToolWindowContent.java @@ -4,6 +4,7 @@ import com.devoxx.genie.model.LanguageModel; import com.devoxx.genie.model.enumarations.ModelProvider; import com.devoxx.genie.service.ConversationStorageService; +import com.devoxx.genie.ui.component.border.AnimatedGlowingBorder; import com.devoxx.genie.ui.listener.SettingsChangeListener; import com.devoxx.genie.ui.panel.ConversationPanel; import com.devoxx.genie.ui.panel.LlmProviderPanel; @@ -55,6 +56,7 @@ public class DevoxxGenieToolWindowContent implements SettingsChangeListener { @Getter private final ConversationStorageService storageService = ConversationStorageService.getInstance(); + private final AnimatedGlowingBorder animatedBorder; /** * The Devoxx Genie Tool Window Content constructor. @@ -69,6 +71,8 @@ public DevoxxGenieToolWindowContent(@NotNull ToolWindow toolWindow) { stateService.loadState(DevoxxGenieStateService.getInstance()); setupMessageBusConnection(toolWindow); + + animatedBorder = new AnimatedGlowingBorder(contentPanel); } private void onStateLoaded() { @@ -105,8 +109,17 @@ private void setupListeners() { llmProviderPanel.getModelNameComboBox().addActionListener(this::processModelNameSelection); } + public void startGlowing() { + animatedBorder.startGlowing(); + } + + public void stopGlowing() { + animatedBorder.stopGlowing(); + } + /** * Create the top panel. + * * @return the top panel */ private @NotNull JPanel createTopPanel() { @@ -118,6 +131,7 @@ private void setupListeners() { /** * Create the splitter. + * * @return the splitter */ private @NotNull Splitter createSplitter() { @@ -126,11 +140,13 @@ private void setupListeners() { splitter.setFirstComponent(promptOutputPanel); splitter.setSecondComponent(submitPanel); splitter.setHonorComponentsMinimumSize(true); + return splitter; } /** * Set up the message bus connection. + * * @param toolWindow the tool window */ private void setupMessageBusConnection(@NotNull ToolWindow toolWindow) { diff --git a/src/main/java/com/devoxx/genie/ui/component/border/AnimatedGlowingBorder.java b/src/main/java/com/devoxx/genie/ui/component/border/AnimatedGlowingBorder.java new file mode 100644 index 00000000..a3e7e38d --- /dev/null +++ b/src/main/java/com/devoxx/genie/ui/component/border/AnimatedGlowingBorder.java @@ -0,0 +1,83 @@ +package com.devoxx.genie.ui.component.border; + +import com.intellij.ui.JBColor; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import javax.swing.border.Border; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class AnimatedGlowingBorder implements Border { + private final Timer glowTimer; + private final GlowingBorder glowingBorder; + private boolean isGlowing = false; + private final JComponent component; + private final Border defaultBorder; + + public AnimatedGlowingBorder(@NotNull JComponent component) { + this.component = component; + this.defaultBorder = BorderFactory.createEmptyBorder(4, 4, 4, 4); + this.glowingBorder = new GlowingBorder(new JBColor(new Color(0, 120, 215), + new Color(0, 120, 213))); + this.glowTimer = createGlowTimer(); + } + + private Timer createGlowTimer() { + return new Timer(50, new ActionListener() { + private float direction = 0.05f; + + @Override + public void actionPerformed(ActionEvent e) { + float alpha = glowingBorder.getAlpha(); + alpha += direction; + if (alpha > 1.0f) { + alpha = 1.0f; + direction = -0.05f; + } else if (alpha < 0.3f) { + alpha = 0.3f; + direction = 0.05f; + } + glowingBorder.setAlpha(alpha); + component.repaint(); + } + }); + } + + public void startGlowing() { + if (!isGlowing) { + isGlowing = true; + component.setBorder(glowingBorder); + glowTimer.start(); + } + } + + public void stopGlowing() { + if (isGlowing) { + isGlowing = false; + glowTimer.stop(); + component.setBorder(defaultBorder); + component.repaint(); + } + } + + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + if (isGlowing) { + glowingBorder.paintBorder(c, g, x, y, width, height); + } else { + defaultBorder.paintBorder(c, g, x, y, width, height); + } + } + + @Override + public Insets getBorderInsets(Component c) { + return isGlowing ? glowingBorder.getBorderInsets(c) : defaultBorder.getBorderInsets(c); + } + + @Override + public boolean isBorderOpaque() { + return false; + } +} diff --git a/src/main/java/com/devoxx/genie/ui/component/GlowingBorder.java b/src/main/java/com/devoxx/genie/ui/component/border/GlowingBorder.java similarity index 96% rename from src/main/java/com/devoxx/genie/ui/component/GlowingBorder.java rename to src/main/java/com/devoxx/genie/ui/component/border/GlowingBorder.java index ddcc85e4..2a15e3df 100644 --- a/src/main/java/com/devoxx/genie/ui/component/GlowingBorder.java +++ b/src/main/java/com/devoxx/genie/ui/component/border/GlowingBorder.java @@ -1,4 +1,4 @@ -package com.devoxx.genie.ui.component; +package com.devoxx.genie.ui.component.border; import com.intellij.util.ui.JBUI; import lombok.Getter; diff --git a/src/main/java/com/devoxx/genie/ui/component/input/PromptInputArea.java b/src/main/java/com/devoxx/genie/ui/component/input/PromptInputArea.java index 82911588..1e87b654 100644 --- a/src/main/java/com/devoxx/genie/ui/component/input/PromptInputArea.java +++ b/src/main/java/com/devoxx/genie/ui/component/input/PromptInputArea.java @@ -1,6 +1,5 @@ package com.devoxx.genie.ui.component.input; -import com.devoxx.genie.ui.component.GlowingBorder; import com.devoxx.genie.ui.listener.PromptInputFocusListener; import com.devoxx.genie.ui.panel.SearchOptionsPanel; import com.intellij.openapi.application.ApplicationManager; @@ -16,9 +15,6 @@ public class PromptInputArea extends JPanel { private final CommandAutoCompleteTextField inputField; - private final GlowingBorder glowingBorder; - private final Timer glowTimer; - private boolean isGlowing = false; public PromptInputArea(@NotNull ResourceBundle resourceBundle, Project project) { super(new BorderLayout()); @@ -34,54 +30,11 @@ public PromptInputArea(@NotNull ResourceBundle resourceBundle, Project project) inputField.setRows(3); - glowingBorder = new GlowingBorder(new JBColor(new Color(0, 120, 215), new Color(0, 120, 213))); - setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); - // Add components to main panel inputAreaPanel.add(new SearchOptionsPanel(), BorderLayout.NORTH); inputAreaPanel.add(inputField, BorderLayout.CENTER); add(inputAreaPanel, BorderLayout.CENTER); - - glowTimer = getGlowTimer(); - } - - private Timer getGlowTimer() { - return new Timer(50, new ActionListener() { - private float direction = 0.05f; - - @Override - public void actionPerformed(ActionEvent e) { - float alpha = glowingBorder.getAlpha(); - alpha += direction; - if (alpha > 1.0f) { - alpha = 1.0f; - direction = -0.05f; - } else if (alpha < 0.3f) { - alpha = 0.3f; - direction = 0.05f; - } - glowingBorder.setAlpha(alpha); - repaint(); - } - }); - } - - public void startGlowing() { - if (!isGlowing) { - isGlowing = true; - setBorder(glowingBorder); - glowTimer.start(); - } - } - - public void stopGlowing() { - if (isGlowing) { - isGlowing = false; - glowTimer.stop(); - setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); - repaint(); - } } public String getText() { diff --git a/src/main/java/com/devoxx/genie/ui/panel/ActionButtonsPanel.java b/src/main/java/com/devoxx/genie/ui/panel/ActionButtonsPanel.java index 39153559..3a05ecda 100644 --- a/src/main/java/com/devoxx/genie/ui/panel/ActionButtonsPanel.java +++ b/src/main/java/com/devoxx/genie/ui/panel/ActionButtonsPanel.java @@ -69,8 +69,10 @@ public class ActionButtonsPanel extends JPanel implements SettingsChangeListener private final transient ActionPanelController controller; private final JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0)); + private final SubmitPanel submitPanel; public ActionButtonsPanel(Project project, + SubmitPanel submitPanel, PromptInputArea promptInputArea, PromptOutputPanel promptOutputPanel, ComboBox llmProvidersComboBox, @@ -81,6 +83,7 @@ public ActionButtonsPanel(Project project, // Initialize fields and components this.project = project; + this.submitPanel = submitPanel; this.promptInputArea = promptInputArea; this.editorFileButtonManager = new EditorFileButtonManager(project, addFileBtn); this.llmProvidersComboBox = llmProvidersComboBox; @@ -207,7 +210,7 @@ private void onSubmitPrompt(ActionEvent actionEvent) { private void disableUIForPromptExecution() { disableSubmitBtn(); disableButtons(); - promptInputArea.startGlowing(); + submitPanel.startGlowing(); } public void enableButtons() { @@ -215,7 +218,7 @@ public void enableButtons() { submitBtn.setIcon(SubmitIcon); submitBtn.setToolTipText(SUBMIT_THE_PROMPT + " (Ctrl+Enter)"); promptInputArea.setEnabled(true); - promptInputArea.stopGlowing(); + submitPanel.stopGlowing(); }); } diff --git a/src/main/java/com/devoxx/genie/ui/panel/SubmitPanel.java b/src/main/java/com/devoxx/genie/ui/panel/SubmitPanel.java index c67f51c2..12012ee8 100644 --- a/src/main/java/com/devoxx/genie/ui/panel/SubmitPanel.java +++ b/src/main/java/com/devoxx/genie/ui/panel/SubmitPanel.java @@ -28,8 +28,7 @@ public class SubmitPanel extends JBPanel { * * @param toolWindowContent the tool window content */ - public SubmitPanel(DevoxxGenieToolWindowContent toolWindowContent) - { + public SubmitPanel(DevoxxGenieToolWindowContent toolWindowContent) { super(new BorderLayout()); this.toolWindowContent = toolWindowContent; this.project = toolWindowContent.getProject(); @@ -49,6 +48,14 @@ public SubmitPanel(DevoxxGenieToolWindowContent toolWindowContent) add(submitPanel); } + public void startGlowing() { + this.toolWindowContent.startGlowing(); + } + + public void stopGlowing() { + this.toolWindowContent.stopGlowing(); + } + @Override public Dimension getMinimumSize() { return new Dimension(0, 150); @@ -62,6 +69,7 @@ public Dimension getMinimumSize() { @Contract(" -> new") private @NotNull JPanel createActionButtonsPanel() { actionButtonsPanel = new ActionButtonsPanel(project, + this, promptInputArea, toolWindowContent.getPromptOutputPanel(), toolWindowContent.getLlmProviderPanel().getModelProviderComboBox(), diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index bca927cc..f09dee82 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,2 +1,2 @@ -#Tue Dec 10 11:05:00 CET 2024 +#Tue Dec 10 15:40:30 CET 2024 version=0.4.1