Skip to content

Commit

Permalink
Merge pull request #364 from devoxx/feature-panel-glowing
Browse files Browse the repository at this point in the history
Panel glowing
  • Loading branch information
stephanj authored Dec 11, 2024
2 parents 7a2f46b + 1c06a17 commit 68972e1
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand All @@ -69,6 +71,8 @@ public DevoxxGenieToolWindowContent(@NotNull ToolWindow toolWindow) {
stateService.loadState(DevoxxGenieStateService.getInstance());

setupMessageBusConnection(toolWindow);

animatedBorder = new AnimatedGlowingBorder(contentPanel);
}

private void onStateLoaded() {
Expand Down Expand Up @@ -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() {
Expand All @@ -118,6 +131,7 @@ private void setupListeners() {

/**
* Create the splitter.
*
* @return the splitter
*/
private @NotNull Splitter createSplitter() {
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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());
Expand All @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ModelProvider> llmProvidersComboBox,
Expand All @@ -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;
Expand Down Expand Up @@ -207,15 +210,15 @@ private void onSubmitPrompt(ActionEvent actionEvent) {
private void disableUIForPromptExecution() {
disableSubmitBtn();
disableButtons();
promptInputArea.startGlowing();
submitPanel.startGlowing();
}

public void enableButtons() {
ApplicationManager.getApplication().invokeLater(() -> {
submitBtn.setIcon(SubmitIcon);
submitBtn.setToolTipText(SUBMIT_THE_PROMPT + " (Ctrl+Enter)");
promptInputArea.setEnabled(true);
promptInputArea.stopGlowing();
submitPanel.stopGlowing();
});
}

Expand Down
12 changes: 10 additions & 2 deletions src/main/java/com/devoxx/genie/ui/panel/SubmitPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ public class SubmitPanel extends JBPanel<SubmitPanel> {
*
* @param toolWindowContent the tool window content
*/
public SubmitPanel(DevoxxGenieToolWindowContent toolWindowContent)
{
public SubmitPanel(DevoxxGenieToolWindowContent toolWindowContent) {
super(new BorderLayout());
this.toolWindowContent = toolWindowContent;
this.project = toolWindowContent.getProject();
Expand All @@ -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);
Expand All @@ -62,6 +69,7 @@ public Dimension getMinimumSize() {
@Contract(" -> new")
private @NotNull JPanel createActionButtonsPanel() {
actionButtonsPanel = new ActionButtonsPanel(project,
this,
promptInputArea,
toolWindowContent.getPromptOutputPanel(),
toolWindowContent.getLlmProviderPanel().getModelProviderComboBox(),
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#Tue Dec 10 11:05:00 CET 2024
#Tue Dec 10 15:40:30 CET 2024
version=0.4.1

0 comments on commit 68972e1

Please sign in to comment.