Addressing issue #632 Visual clues in chat windows about unread messages.

cusax-fix
Yana Stamcheva 17 years ago
parent 5fdbc090d6
commit 654d1fb56b

@ -69,7 +69,7 @@ service.gui.INACTIVE_TEXT=999999
service.gui.MENU_DISABLED_FOREGROUND=999999 service.gui.MENU_DISABLED_FOREGROUND=999999
# Color used in tab title for non read incoming messages. # Color used in tab title for non read incoming messages.
service.gui.TAB_TITLE_HIGHLIGHT=F9750A service.gui.TAB_TITLE_HIGHLIGHT=DE4900
# Tab default text color. # Tab default text color.
service.gui.TAB_TITLE=474747 service.gui.TAB_TITLE=474747
@ -98,7 +98,7 @@ service.gui.GRADIENT_DARK_COLOR=E6E6E6
service.gui.GRADIENT_LIGHT_COLOR=FFFFFF service.gui.GRADIENT_LIGHT_COLOR=FFFFFF
# Used for some custom borders, like the border in the chat window. # Used for some custom borders, like the border in the chat window.
service.gui.BORDER_COLOR=929292 service.gui.BORDER_COLOR=8EA0BC
# Splash screen text color. # Splash screen text color.
service.gui.SPLASH_SCREEN_TEXT_COLOR=333333 service.gui.SPLASH_SCREEN_TEXT_COLOR=333333

@ -71,6 +71,8 @@ public class ChatPanel
private ChatRoomSubjectPanel subjectPanel; private ChatRoomSubjectPanel subjectPanel;
public int unreadMessageNumber = 0;
/** /**
* Indicates that a typing notification event is successfully sent. * Indicates that a typing notification event is successfully sent.
*/ */
@ -1545,4 +1547,14 @@ public void fireChatFocusEvent(int eventID)
} }
} }
} }
/**
* Returns the number of messages received but not yet read from the user.
*
* @return the number of messages received but not yet read from the user.
*/
public int getUnreadMessageNumber()
{
return unreadMessageNumber;
}
} }

@ -13,7 +13,6 @@
import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.lookandfeel.*; import net.java.sip.communicator.impl.gui.lookandfeel.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.*; import net.java.sip.communicator.util.swing.*;

@ -0,0 +1,75 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.gui.main.chat;
import net.java.sip.communicator.util.swing.*;
/**
* The <tt>ChatTabbedPane</tt> is a <tt>SIPCommTabbedPane</tt> that takes into
* account the number of unread messages received in a certain tab and shows
* this information to the user.
*
* @author Yana Stamcheva
*/
public class ChatTabbedPane
extends SIPCommTabbedPane
{
/**
* Creates a <tt>ChatTabbedPane</tt> with a close tab funcion.
*/
public ChatTabbedPane()
{
super(true, false);
}
/**
* Overrides setSelectedIndex in SIPCommTabbedPane in order to remove the
* indicator of number of unread messages previously set.
*
* @param tabIndex the index of the tab to be selected
*/
public void setSelectedIndex(int tabIndex)
{
if (tabIndex < 0)
return;
String tabTitle = this.getTitleAt(tabIndex);
int bracketIndex = tabTitle.indexOf("(");
if (bracketIndex > - 1)
tabTitle = tabTitle.substring(0, bracketIndex);
this.setTitleAt(tabIndex, tabTitle);
ChatPanel chatPanel = (ChatPanel) this.getComponentAt(tabIndex);
chatPanel.unreadMessageNumber = 0;
super.setSelectedIndex(tabIndex);
}
/**
* When a tab is highlighted sets an indicator of the number of unread
* messages in this tab.
*
* @param tabIndex the index of the tab
*/
public void highlightTab(int tabIndex, int unreadMessageNumber)
{
String tabTitle = this.getTitleAt(tabIndex);
int bracketIndex = tabTitle.indexOf("(");
if (bracketIndex > - 1)
tabTitle = tabTitle.substring(0, bracketIndex + 1)
+ unreadMessageNumber + ")";
else
tabTitle = tabTitle + "(" + unreadMessageNumber + ")";
this.setTitleAt(tabIndex, tabTitle);
super.highlightTab(tabIndex);
}
}

@ -21,7 +21,6 @@
import net.java.sip.communicator.impl.gui.main.contactlist.*; import net.java.sip.communicator.impl.gui.main.contactlist.*;
import net.java.sip.communicator.impl.gui.main.contactlist.addcontact.*; import net.java.sip.communicator.impl.gui.main.contactlist.addcontact.*;
import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.impl.gui.utils.Constants;
import net.java.sip.communicator.service.contactlist.*; import net.java.sip.communicator.service.contactlist.*;
import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.gui.Container; import net.java.sip.communicator.service.gui.Container;
@ -54,7 +53,7 @@ public class ChatWindow
{ {
private final Logger logger = Logger.getLogger(ChatWindow.class); private final Logger logger = Logger.getLogger(ChatWindow.class);
private SIPCommTabbedPane chatTabbedPane = null; private ChatTabbedPane chatTabbedPane = null;
private int chatCount = 0; private int chatCount = 0;
@ -98,7 +97,7 @@ public ChatWindow()
//If in mode TABBED_CHAT_WINDOW initialize the tabbed pane //If in mode TABBED_CHAT_WINDOW initialize the tabbed pane
if(ConfigurationManager.isMultiChatWindowEnabled()) if(ConfigurationManager.isMultiChatWindowEnabled())
{ {
chatTabbedPane = new SIPCommTabbedPane(true, false); chatTabbedPane = new ChatTabbedPane();
chatTabbedPane.addCloseListener(new CloseListener() chatTabbedPane.addCloseListener(new CloseListener()
{ {
@ -498,8 +497,12 @@ public int getChatTabCount()
*/ */
public void highlightTab(ChatPanel chatPanel) public void highlightTab(ChatPanel chatPanel)
{ {
this.chatTabbedPane.highlightTab( int tabIndex = chatTabbedPane.indexOfComponent(chatPanel);
chatTabbedPane.indexOfComponent(chatPanel));
chatPanel.unreadMessageNumber ++;
this.chatTabbedPane
.highlightTab(tabIndex, chatPanel.getUnreadMessageNumber());
} }
/** /**

@ -32,7 +32,7 @@ public class ChatWindowManager
private final Object syncChat = new Object(); private final Object syncChat = new Object();
/** /**
* Opens a the specified chatPanel and brings it to the front if so * Opens the specified chatPanel and brings it to the front if so
* specified. * specified.
* *
* @param chatPanel the chat panel that we will be opening * @param chatPanel the chat panel that we will be opening

@ -424,7 +424,8 @@ public void firePopupOutsideTabEvent(MouseEvent e)
*/ */
public void setSelectedIndex(int tabIndex) public void setSelectedIndex(int tabIndex)
{ {
SIPCommTabbedPaneUI ui = (SIPCommTabbedPaneUI) this.getUI(); SIPCommTabbedPaneEnhancedUI ui
= (SIPCommTabbedPaneEnhancedUI) this.getUI();
if (ui.isTabHighlighted(tabIndex)) if (ui.isTabHighlighted(tabIndex))
{ {
ui.tabRemoveHighlight(tabIndex); ui.tabRemoveHighlight(tabIndex);
@ -439,7 +440,8 @@ public void setSelectedIndex(int tabIndex)
*/ */
public void highlightTab(int tabIndex) public void highlightTab(int tabIndex)
{ {
SIPCommTabbedPaneUI ui = (SIPCommTabbedPaneUI) this.getUI(); SIPCommTabbedPaneEnhancedUI ui
= (SIPCommTabbedPaneEnhancedUI) this.getUI();
if (!ui.isTabHighlighted(tabIndex) if (!ui.isTabHighlighted(tabIndex)
&& this.getSelectedIndex() != tabIndex) && this.getSelectedIndex() != tabIndex)
@ -447,7 +449,7 @@ public void highlightTab(int tabIndex)
this.repaint(); this.repaint();
} }
public void removeTabAt(int index) public void removeTabAt(int index)
{ {
if (index < lastSelectedIndex) if (index < lastSelectedIndex)
@ -461,7 +463,7 @@ else if (index > lastSelectedIndex)
super.removeTabAt(index); super.removeTabAt(index);
} }
public void stateChanged(ChangeEvent e) public void stateChanged(ChangeEvent e)
{ {
lastSelectedIndex = this.getSelectedIndex(); lastSelectedIndex = this.getSelectedIndex();

@ -14,6 +14,7 @@
import java.awt.*; import java.awt.*;
import java.awt.image.*; import java.awt.image.*;
import java.util.*;
import javax.swing.*; import javax.swing.*;
import javax.swing.plaf.*; import javax.swing.plaf.*;
@ -83,25 +84,27 @@ public class SIPCommTabbedPaneEnhancedUI
private static final String TAB_RIGHT_BG = private static final String TAB_RIGHT_BG =
"service.gui.lookandfeel.TAB_RIGHT_BG"; "service.gui.lookandfeel.TAB_RIGHT_BG";
public static ComponentUI createUI(JComponent c) { protected final java.util.List<Integer> highlightedTabs
= new Vector<Integer>();
public static ComponentUI createUI(JComponent c)
{
return new SIPCommTabbedPaneEnhancedUI(); return new SIPCommTabbedPaneEnhancedUI();
} }
protected void paintFocusIndicator(Graphics g, int tabPlacement, protected void paintFocusIndicator(Graphics g, int tabPlacement,
Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle[] rects, int tabIndex, Rectangle iconRect,
Rectangle textRect, boolean isSelected) { Rectangle textRect, boolean isSelected) {}
}
/** /**
* Overriden to paint nothing. * Overriden to paint nothing.
*/ */
protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex,
int x, int y, int w, int h, boolean isSelected) { int x, int y, int w, int h, boolean isSelected) {}
}
protected void paintContentBorderTopEdge(Graphics g, int tabPlacement, protected void paintContentBorderTopEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) { int selectedIndex, int x, int y, int w, int h)
{
if (tabPane.getTabCount() < 1) if (tabPane.getTabCount() < 1)
return; return;
@ -110,8 +113,8 @@ protected void paintContentBorderTopEdge(Graphics g, int tabPlacement,
} }
protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement, protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) { int selectedIndex, int x, int y, int w, int h)
{
if (tabPane.getTabCount() < 1) if (tabPane.getTabCount() < 1)
return; return;
@ -121,8 +124,8 @@ protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
} }
protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement, protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) { int selectedIndex, int x, int y, int w, int h)
{
if (tabPane.getTabCount() < 1) if (tabPane.getTabCount() < 1)
return; return;
@ -135,8 +138,8 @@ protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
} }
protected void paintContentBorderRightEdge(Graphics g, int tabPlacement, protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) { int selectedIndex, int x, int y, int w, int h)
{
if (tabPane.getTabCount() < 1) if (tabPane.getTabCount() < 1)
return; return;
@ -170,13 +173,13 @@ private void internalPaintTabBackground(Graphics g, int tabPlacement,
BufferedImage leftImg = null; BufferedImage leftImg = null;
BufferedImage middleImg = null; BufferedImage middleImg = null;
BufferedImage rightImg = null; BufferedImage rightImg = null;
Graphics2D g2 = (Graphics2D) g; Graphics2D g2 = (Graphics2D) g;
AntialiasingManager.activateAntialiasing(g2); AntialiasingManager.activateAntialiasing(g2);
int tabOverlap = 0; int tabOverlap = 0;
if (isSelected) if (isSelected)
{ {
if (tabPane.isEnabledAt(tabIndex)) if (tabPane.isEnabledAt(tabIndex))
@ -210,8 +213,8 @@ private void internalPaintTabBackground(Graphics g, int tabPlacement,
protected void paintText(Graphics g, int tabPlacement, Font font, protected void paintText(Graphics g, int tabPlacement, Font font,
FontMetrics metrics, int tabIndex, String title, FontMetrics metrics, int tabIndex, String title,
Rectangle textRect, boolean isSelected) { Rectangle textRect, boolean isSelected)
{
g.setFont(font); g.setFont(font);
int titleWidth = SwingUtilities.computeStringWidth(metrics, title); int titleWidth = SwingUtilities.computeStringWidth(metrics, title);
@ -220,18 +223,20 @@ protected void paintText(Graphics g, int tabPlacement, Font font,
if (isOneActionButtonEnabled()) { if (isOneActionButtonEnabled()) {
preferredWidth = calculateTabWidth(tabPlacement, tabIndex, metrics) preferredWidth = calculateTabWidth(tabPlacement, tabIndex, metrics)
- WIDTHDELTA - 15; - WIDTHDELTA - 15;
if (isCloseEnabled()) if (isCloseEnabled())
preferredWidth -= BUTTONSIZE; preferredWidth -= BUTTONSIZE;
if (isMaxEnabled()) if (isMaxEnabled())
preferredWidth -= BUTTONSIZE; preferredWidth -= BUTTONSIZE;
} }
else { else
{
preferredWidth = titleWidth; preferredWidth = titleWidth;
} }
while (titleWidth > preferredWidth) { while (titleWidth > preferredWidth)
{
if (title.endsWith("...")) if (title.endsWith("..."))
title = title.substring(0, title.indexOf("...") - 1) title = title.substring(0, title.indexOf("...") - 1)
.concat("..."); .concat("...");
@ -245,29 +250,37 @@ protected void paintText(Graphics g, int tabPlacement, Font font,
textRect.width = titleWidth; textRect.width = titleWidth;
View v = getTextViewForTab(tabIndex); View v = getTextViewForTab(tabIndex);
if (v != null) { if (v != null)
{
// html // html
v.paint(g, textRect); v.paint(g, textRect);
} else { }
else
{
// plain text // plain text
int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex); int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);
if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex)) { if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex))
{
if (isSelected) if (isSelected)
g.setColor(whiteColor); g.setColor(whiteColor);
else { else
if (this.isTabHighlighted(tabIndex)) { {
g.setColor( if (this.isTabHighlighted(tabIndex))
UIManager.getColor("TabbedPane.tabTitleHighlight")); {
} else g.setColor(new Color(UtilActivator.getResources()
.getColor("service.gui.TAB_TITLE_HIGHLIGHT")));
}
else
g.setColor(tabPane.getForegroundAt(tabIndex)); g.setColor(tabPane.getForegroundAt(tabIndex));
} }
BasicGraphicsUtils BasicGraphicsUtils
.drawStringUnderlineCharAt(g, title, mnemIndex, .drawString(g, title, mnemIndex,
textRect.x, textRect.y + metrics.getAscent()); textRect.x, textRect.y + metrics.getAscent());
}
} else { // tab disabled else
{ // tab disabled
g.setColor(tabPane.getBackgroundAt(tabIndex).brighter()); g.setColor(tabPane.getBackgroundAt(tabIndex).brighter());
BasicGraphicsUtils BasicGraphicsUtils
.drawStringUnderlineCharAt(g, title, mnemIndex, .drawStringUnderlineCharAt(g, title, mnemIndex,
@ -282,18 +295,21 @@ protected void paintText(Graphics g, int tabPlacement, Font font,
} }
protected class ScrollableTabButton extends protected class ScrollableTabButton extends
SIPCommTabbedPaneUI.ScrollableTabButton { SIPCommTabbedPaneUI.ScrollableTabButton
{
public ScrollableTabButton(int direction) { public ScrollableTabButton(int direction)
{
super(direction); super(direction);
setRolloverEnabled(true); setRolloverEnabled(true);
} }
public Dimension getPreferredSize() { public Dimension getPreferredSize()
{
return new Dimension(16, calculateMaxTabHeight(0)); return new Dimension(16, calculateMaxTabHeight(0));
} }
public void paint(Graphics g) { public void paint(Graphics g)
{
Color origColor; Color origColor;
boolean isPressed, isRollOver, isEnabled; boolean isPressed, isRollOver, isEnabled;
int w, h, size; int w, h, size;
@ -377,22 +393,48 @@ public void paint(Graphics g) {
} }
protected SIPCommTabbedPaneUI.ScrollableTabButton createScrollableTabButton( protected SIPCommTabbedPaneUI.ScrollableTabButton createScrollableTabButton(
int direction) { int direction)
{
return new ScrollableTabButton(direction); return new ScrollableTabButton(direction);
} }
protected int calculateTabWidth(int tabPlacement, int tabIndex, protected int calculateTabWidth(int tabPlacement, int tabIndex,
FontMetrics metrics) { FontMetrics metrics)
{
int width = super.calculateTabWidth(tabPlacement, tabIndex, metrics); int width = super.calculateTabWidth(tabPlacement, tabIndex, metrics);
if (isOneActionButtonEnabled()) if (isOneActionButtonEnabled())
{ {
if(width > PREFERRED_WIDTH) if(width > PREFERRED_WIDTH)
width = PREFERRED_WIDTH; width = PREFERRED_WIDTH;
} }
return width + WIDTHDELTA; return width + WIDTHDELTA;
} }
public void tabAddHightlight(int tabIndex)
{
this.highlightedTabs.add(tabIndex);
}
public void tabRemoveHighlight(int tabIndex)
{
Iterator<Integer> highlightedIter = highlightedTabs.iterator();
while (highlightedIter.hasNext())
{
if (highlightedIter.next().intValue() == tabIndex)
{
highlightedIter.remove();
break;
}
}
}
public boolean isTabHighlighted(int tabIndex)
{
return highlightedTabs.contains(tabIndex);
}
} }

@ -111,9 +111,6 @@ public class SIPCommTabbedPaneUI
protected JMenuItem closeItem; protected JMenuItem closeItem;
protected final java.util.List<Integer> highlightedTabs
= new Vector<Integer>();
public SIPCommTabbedPaneUI() public SIPCommTabbedPaneUI()
{ {
//closeImgB = UtilActivator.getImage(CLOSE_TAB_SELECTED_ICON); //closeImgB = UtilActivator.getImage(CLOSE_TAB_SELECTED_ICON);
@ -1725,36 +1722,11 @@ public void mouseDragged(MouseEvent e)
} }
} }
public void tabAddHightlight(int tabIndex)
{
this.highlightedTabs.add(tabIndex);
}
public void tabRemoveHighlight(int tabIndex)
{
Iterator<Integer> highlightedIter = highlightedTabs.iterator();
while (highlightedIter.hasNext())
{
if (highlightedIter.next().intValue() == tabIndex)
{
highlightedIter.remove();
break;
}
}
}
public boolean isTabHighlighted(int tabIndex)
{
return highlightedTabs.contains(tabIndex);
}
/** /**
* We don't want to have a content border. * We don't want to have a content border.
*/ */
protected void paintContentBorder( Graphics g, protected void paintContentBorder( Graphics g,
int tabPlacement, int tabPlacement,
int selectedIndex) int selectedIndex)
{ {}
}
} }

Loading…
Cancel
Save