Ongoing work on partial desktop sharing user interface.

cusax-fix
Yana Stamcheva 15 years ago
parent 9ed22ae826
commit 7ab0b8ca79

@ -7,6 +7,7 @@ org.osgi.framework.system.packages.extra= \
com.apple.cocoa.foundation; \
com.apple.eawt; \
com.apple.eio; \
com.sun.awt; \
net.java.sip.communicator.util.launchutils; \
org.apache.xml.serialize; \
org.jdesktop.jdic.desktop; \

@ -101,6 +101,7 @@ service.gui.icons.VOICEMAIL=resources/images/impl/gui/common/voicemail.png
service.gui.icons.SEND_SMS=resources/images/impl/gui/common/sms.png
service.gui.icons.SEND_SMS_SELECTED=resources/images/impl/gui/common/smsSelected.png
service.gui.icons.TYPING=resources/images/impl/gui/common/typing.gif
service.gui.icons.WINDOW_RESIZE_ICON=resources/images/impl/gui/common/windowResizeIcon.png
# Status icons
service.gui.statusicons.USER_ONLINE_ICON=resources/images/impl/gui/common/statusicons/online.png
@ -202,6 +203,7 @@ service.gui.buttons.ZOOM_IN=resources/images/impl/gui/buttons/magnifier_zoom_in.
service.gui.buttons.RESET=resources/images/impl/gui/buttons/reset.png
service.gui.buttons.VOLUME_CONTROL=resources/images/impl/gui/buttons/volumeControl.png
service.gui.buttons.CLOSE_VIDEO=resources/images/impl/gui/buttons/closeVideo.png
service.gui.buttons.TRANSPARENT_WINDOW_BUTTON=resources/images/impl/gui/buttons/transparentWindowButton.png
# Sound level icons
service.gui.soundlevel.SOUND_LEVEL_ACTIVE=resources/images/impl/gui/common/soundlevel/soundActive.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="New document 1">
<defs
id="defs4">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<inkscape:perspective
id="perspective2830"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="480.02255"
inkscape:cy="899.69334"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-grids="true"
inkscape:snap-to-guides="true"
inkscape:window-width="1227"
inkscape:window-height="703"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#030000;fill-opacity:1;stroke:none"
d="M 741.60714,4.2812503 387.29464,360.59375 c 1.77274,2.77846 4.88361,4.625 8.4375,4.625 l 49.875,0 300.125,-301.59375 0,-51.25 c 0,-3.3367797 -1.62759,-6.2790897 -4.125,-8.0937497 z M 745.73214,252 l 0,0 z m 0,0 -112.59375,113.21875 84.411,-0.50507 c 14.63138,-0.50508 28.18275,-13.0463 28.18275,-27.1726 l 0,-85.54108 z m -172.28125,113.21875 0,0 z m 0,0 172.28125,-175.27031 0,-63.79219 -237.90625,239.0625 65.625,0 z"
id="rect2818"
sodipodi:nodetypes="ccccccccccccccccccccc"
inkscape:export-filename="/Users/yanastamcheva/workspace/trunk/resources/images/impl/gui/common/windowResizeIcon.png"
inkscape:export-xdpi="3.0130775"
inkscape:export-ydpi="3.0130775" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

@ -390,6 +390,8 @@ service.gui.SET_STATUS_MESSAGE=Set status message
service.gui.SETTINGS=&Options
service.gui.SHARE_DESKTOP=&Share desktop
service.gui.SHARE_DESKTOP_WITH_CONTACT=Share desktop with contact
service.gui.SHARE_FULL_SCREEN=Share full screen
service.gui.SHARE_REGION=Share region
service.gui.SHOW=Show
service.gui.SHOW_CONTACT_LIST_TOOL_TIP=Click here to switch off the history view and show your contact list.
service.gui.SHOW_OFFLINE_CONTACTS=Show offline contacts
@ -399,11 +401,13 @@ service.gui.SMS_SEND_CONNECTION_PROBLEM=You need to be connected before being ab
service.gui.SPECIFY_REASON=In the field below you could specify the reason of this operation.
service.gui.SOUND_OFF=Turn sound off
service.gui.SOUND_ON=Turn sound on
service.gui.START_SHARING=Start sharing
service.gui.STATUS=Status:
service.gui.STATUS_CHANGED_CHAT_MESSAGE=has become {0}
service.gui.STATUS_CHANGE_GENERAL_ERROR=Failed to change status for account: User name: {0}, Server name: {1}, due to a general error.
service.gui.STATUS_CHANGE_NETWORK_FAILURE=Failed to change status for account: User name: {0}, Server name: {1}, due to a network problem.
service.gui.STATUS_MESSAGE_INFO=In the field below you can specify the new message you would like to use.
service.gui.STOP_SHARING=Stop sharing
service.gui.SUBJECT=Subject
service.gui.SUMMARY=Summary
service.gui.TODAY=Today

@ -8,7 +8,6 @@
import java.text.*;
import java.util.*;
import java.util.List;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.customcontrols.*;
@ -16,10 +15,12 @@
import net.java.sip.communicator.impl.gui.main.contactlist.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.contactlist.*;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.neomedia.device.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.transparent.*;
/**
* The <tt>CallManager</tt> is the one that handles calls. It contains also
@ -315,8 +316,56 @@ public static void createDesktopSharing(
ProtocolProviderService protocolProvider,
String contact)
{
// Use the default media device corresponding to the screen to share
createDesktopSharing(protocolProvider, contact, null);
// If the user presses cancel on the desktop sharing warning then we
// have nothing more to do here.
if (!showDesktopSharingWarning())
return;
MediaService mediaService = GuiActivator.getMediaService();
List<MediaDevice> desktopDevices = mediaService.getDevices(
MediaType.VIDEO, MediaUseCase.DESKTOP);
int deviceNumber = desktopDevices.size();
if (deviceNumber == 1)
{
createDesktopSharing(
protocolProvider, contact, desktopDevices.get(0));
}
else if (deviceNumber > 1)
{
SelectScreenDialog selectDialog
= new SelectScreenDialog(desktopDevices);
selectDialog.setVisible(true);
createDesktopSharing( protocolProvider,
contact,
selectDialog.getSelectedDevice());
}
}
/**
* Creates a region desktop sharing through the given
* <tt>protocolProvider</tt> with the given <tt>contact</tt>.
*
* @param protocolProvider the <tt>ProtocolProviderService</tt>, through
* which the sharing session will be established
* @param contact the address of the contact recipient
*/
public static void createRegionDesktopSharing(
ProtocolProviderService protocolProvider,
String contact)
{
if (showDesktopSharingWarning())
{
TransparentFrame frame = DesktopSharingFrame.createTransparentFrame(
protocolProvider, contact, true);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
/**
@ -325,21 +374,63 @@ public static void createDesktopSharing(
*
* @param protocolProvider the protocol provider to which this call belongs.
* @param contact the contact to call to
* @param mediaDevice the media device corresponding to the screen to share
* @param x the x coordinate of the shared region
* @param y the y coordinated of the shared region
* @param width the width of the shared region
* @param height the height of the shared region
*/
public static void createDesktopSharing(
public static void createRegionDesktopSharing(
ProtocolProviderService protocolProvider,
String contact,
MediaDevice mediaDevice)
int x,
int y,
int width,
int height)
{
if (showDesktopSharingWarning())
MediaService mediaService = GuiActivator.getMediaService();
List<MediaDevice> desktopDevices = mediaService.getDevices(
MediaType.VIDEO, MediaUseCase.DESKTOP);
int deviceNumber = desktopDevices.size();
if (deviceNumber == 1)
{
createDesktopSharing(protocolProvider, contact,
mediaService.getMediaDeviceForPartialDesktopStreaming(
desktopDevices.get(0), width, height, x, y));
}
else if (deviceNumber > 1)
{
new CreateDesktopSharingThread( protocolProvider,
contact,
mediaDevice).start();
SelectScreenDialog selectDialog
= new SelectScreenDialog(desktopDevices);
selectDialog.setVisible(true);
createDesktopSharing(protocolProvider, contact,
mediaService.getMediaDeviceForPartialDesktopStreaming(
selectDialog.getSelectedDevice(), width, height, x, y));
}
}
/**
* Creates a desktop sharing call to the contact represented by the given
* string.
*
* @param protocolProvider the protocol provider to which this call belongs.
* @param contact the contact to call to
* @param mediaDevice the media device corresponding to the screen to share
*/
private static void createDesktopSharing(
ProtocolProviderService protocolProvider,
String contact,
MediaDevice mediaDevice)
{
new CreateDesktopSharingThread( protocolProvider,
contact,
mediaDevice).start();
}
/**
* Enables the desktop sharing in an existing <tt>call</tt>.
*
@ -349,7 +440,102 @@ public static void createDesktopSharing(
*/
public static void enableDesktopSharing(Call call, boolean enable)
{
enableDesktopSharing(call, null, enable);
if (!enable)
enableDesktopSharing(call, null, enable);
else if (showDesktopSharingWarning())
{
MediaService mediaService = GuiActivator.getMediaService();
List<MediaDevice> desktopDevices = mediaService.getDevices(
MediaType.VIDEO, MediaUseCase.DESKTOP);
int deviceNumber = desktopDevices.size();
if (deviceNumber == 1)
{
enableDesktopSharing(call, null, enable);
}
else if (deviceNumber > 1)
{
SelectScreenDialog selectDialog
= new SelectScreenDialog(desktopDevices);
selectDialog.setVisible(true);
enableDesktopSharing(
call, selectDialog.getSelectedDevice(), enable);
}
}
// in case we switch to video, disable remote control if it was
// enabled
enableDesktopRemoteControl(call.getCallPeers().next(), false);
}
/**
* Enables the region desktop sharing for the given call.
*
* @param call the call, for which the region desktop sharing should be
* enabled
* @param enable indicates if the desktop sharing should be enabled or
* disabled
*/
public static void enableRegionDesktopSharing(Call call, boolean enable)
{
if (!enable)
enableDesktopSharing(call, null, enable);
else if (showDesktopSharingWarning())
{
TransparentFrame frame
= DesktopSharingFrame.createTransparentFrame(call, true);
frame.setVisible(true);
}
}
/**
* Creates a desktop sharing call to the contact represented by the given
* string.
*
* @param call the call for which desktop sharing should be enabled
* @param x the x coordinate of the shared region
* @param y the y coordinated of the shared region
* @param width the width of the shared region
* @param height the height of the shared region
*/
public static void enableRegionDesktopSharing(
Call call,
int x,
int y,
int width,
int height)
{
// Use the default media device corresponding to the screen to share
MediaService mediaService = GuiActivator.getMediaService();
List<MediaDevice> desktopDevices = mediaService.getDevices(
MediaType.VIDEO, MediaUseCase.DESKTOP);
int deviceNumber = desktopDevices.size();
if (deviceNumber == 1)
{
enableDesktopSharing(call,
mediaService.getMediaDeviceForPartialDesktopStreaming(
desktopDevices.get(0), width, height, x, y), true);
}
else if (deviceNumber > 1)
{
SelectScreenDialog selectDialog
= new SelectScreenDialog(desktopDevices);
selectDialog.setVisible(true);
enableDesktopSharing(call,
mediaService.getMediaDeviceForPartialDesktopStreaming(
selectDialog.getSelectedDevice(), width, height, x, y),
true);
}
// in case we switch to video, disable remote control if it was
// enabled
@ -364,7 +550,7 @@ public static void enableDesktopSharing(Call call, boolean enable)
* @param enable indicates if the desktop sharing should be enabled or
* disabled
*/
public static void enableDesktopSharing(Call call,
private static void enableDesktopSharing(Call call,
MediaDevice mediaDevice,
boolean enable)
{
@ -383,27 +569,24 @@ public static void enableDesktopSharing(Call call,
if (enable && isLocalVideoEnabled(call))
enableLocalVideo(call, false);
if (!enable || showDesktopSharingWarning())
try
{
try
{
if (mediaDevice != null)
desktopOpSet.setLocalVideoAllowed(
call,
mediaDevice,
enable);
else
desktopOpSet.setLocalVideoAllowed(
call,
enable);
enableSucceeded = true;
}
catch (OperationFailedException ex)
{
logger.error(
"Failed to toggle the streaming of local video.", ex);
}
if (mediaDevice != null)
desktopOpSet.setLocalVideoAllowed(
call,
mediaDevice,
enable);
else
desktopOpSet.setLocalVideoAllowed(
call,
enable);
enableSucceeded = true;
}
catch (OperationFailedException ex)
{
logger.error(
"Failed to toggle the streaming of local video.", ex);
}
}
@ -433,6 +616,28 @@ public static boolean isDesktopSharingEnabled(Call call)
return false;
}
/**
* Indicates if the desktop sharing is currently enabled for the given
* <tt>call</tt>.
*
* @param call the <tt>Call</tt>, for which we would to check if the desktop
* sharing is currently enabled
* @return <tt>true</tt> if the desktop sharing is currently enabled for the
* given <tt>call</tt>, <tt>false</tt> otherwise
*/
public static boolean isRegionDesktopSharingEnabled(Call call)
{
OperationSetDesktopSharingServer desktopOpSet
= call.getProtocolProvider().getOperationSet(
OperationSetDesktopSharingServer.class);
if (desktopOpSet != null
&& desktopOpSet.isPartialStreaming(call))
return true;
return false;
}
/**
* Enables/disables remote control when in a desktop sharing session with
* the given <tt>callPeer</tt>.

@ -6,12 +6,13 @@
*/
package net.java.sip.communicator.impl.gui.main.call;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.neomedia.device.*;
import net.java.sip.communicator.service.protocol.*;
/**
@ -70,23 +71,67 @@ public void buttonPressed()
// Otherwise we enable the desktop sharing.
else
{
MediaService mediaService = GuiActivator.getMediaService();
//We'll select the button once the desktop sharing has been
// established.
setSelected(false);
List<MediaDevice> desktopDevices = mediaService.getDevices(
MediaType.VIDEO, MediaUseCase.DESKTOP);
JPopupMenu sharingMenu = createDesktopSharingMenu();
int deviceNumber = desktopDevices.size();
Point location = new Point(getX(), getY() + getHeight());
if (deviceNumber == 1)
CallManager.enableDesktopSharing(call, true);
else if (deviceNumber > 1)
{
SelectScreenDialog selectDialog
= new SelectScreenDialog(call, desktopDevices);
SwingUtilities.convertPointToScreen(location, getParent());
selectDialog.setVisible(true);
}
sharingMenu.setLocation(location);
sharingMenu.setVisible(true);
}
}
}
/**
* Creates the menu responsible for desktop sharing when a single desktop
* sharing contact is available.
*
* @return the created popup menu
*/
private JPopupMenu createDesktopSharingMenu()
{
final JPopupMenu popupMenu = new JPopupMenu(
GuiActivator.getResources().getI18NString(
"service.gui.SHARE_DESKTOP"));
popupMenu.setInvoker(this);
popupMenu.setFocusable(true);
JMenuItem shareFullScreen = new JMenuItem(GuiActivator.getResources()
.getI18NString("service.gui.SHARE_FULL_SCREEN"));
JMenuItem shareRegion = new JMenuItem(GuiActivator.getResources()
.getI18NString("service.gui.SHARE_REGION"));
shareRegion.setEnabled(false);
popupMenu.add(shareFullScreen);
popupMenu.add(shareRegion);
shareFullScreen.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
popupMenu.setVisible(false);
CallManager.enableDesktopSharing(call, true);
}
});
shareRegion.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
popupMenu.setVisible(false);
CallManager.enableRegionDesktopSharing(call, true);
}
});
return popupMenu;
}
}

@ -0,0 +1,567 @@
/*
* 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.call;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.beans.*;
import java.util.*;
import javax.swing.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.*;
import net.java.sip.communicator.util.swing.transparent.*;
/**
*
* @author Yana Stamcheva
*/
public class DesktopSharingFrame
{
/**
* Used for logging.
*/
private static final Logger logger
= Logger.getLogger(DesktopSharingFrame.class);
/**
* The icon shown to indicate the resize drag area.
*/
private static final ImageIcon resizeIcon
= GuiActivator.getResources().getImage(
"service.gui.icons.WINDOW_RESIZE_ICON");
/**
* The indent of the sharing region from the frame.
*/
private static int SHARING_REGION_INDENT = 2;
/**
* The x coordinate of the frame, which started the regional sharing.
*/
private static int initialFrameX = -1;
/**
* The y coordinate of the frame, which started the regional sharing.
*/
private static int initialFrameY = -1;
/**
* The width of the sharing region, which started the sharing.
*/
private static int sharingRegionWidth = -1;
/**
* The height of the sharing region, which started the sharing.
*/
private static int sharingRegionHeight = -1;
/**
* A mapping of a desktop sharing frame created by this class and a call.
*/
private static final Map<Call, JFrame> callDesktopFrames
= new Hashtable<Call, JFrame>();
/**
* Creates the transparent desktop sharing frame.
*
* @param protocolProvider the protocol provider, through which the desktop
* sharing will pass
* @param contactAddress the address of the contact to call
* @param initialFrame indicates if this is the frame which initiates the
* desktop sharing
* @return the created desktop sharing frame
*/
public static TransparentFrame createTransparentFrame(
ProtocolProviderService protocolProvider,
String contactAddress,
boolean initialFrame)
{
TransparentFrame frame = TransparentFrame.createTransparentFrame();
initContentPane(frame, initialFrame);
JComponent sharingRegion = new TransparentPanel();
// The preferred width on MacOSX should be a multiple of 16, that's why
// we put 592 as a default width.
sharingRegion.setPreferredSize(new Dimension(592, 400));
frame.getContentPane().add(sharingRegion, BorderLayout.NORTH);
JPanel buttonPanel = initButtons(
frame, sharingRegion, initialFrame, null,
protocolProvider, contactAddress);
frame.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
frame.pack();
return frame;
}
/**
* Creates the transparent desktop sharing frame.
*
* @param call the current call
* @param initialFrame indicates if this is the frame which initiates the
* desktop sharing
* @return the created desktop sharing frame
*/
public static TransparentFrame createTransparentFrame(
Call call,
boolean initialFrame)
{
TransparentFrame frame = TransparentFrame.createTransparentFrame();
initContentPane(frame, initialFrame);
JComponent sharingRegion = new TransparentPanel();
// The preferred width on MacOSX should be a multiple of 16,
// that's why we put 592 as a default width.
sharingRegion.setPreferredSize(new Dimension(592, 400));
frame.getContentPane().add(sharingRegion, BorderLayout.NORTH);
JPanel buttonPanel = initButtons(
frame, sharingRegion, initialFrame, call, null, null);
frame.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
// If the desktop sharing has started we store the frame to call mapping.
if (!initialFrame)
{
callDesktopFrames.put(call, frame);
addCallListener(call, frame);
addFrameListener(call, frame, sharingRegion);
addDesktopSharingListener(call, frame);
logger.info("The sharing region width: " + sharingRegionWidth);
if (sharingRegionWidth > -1 && sharingRegionHeight > -1)
sharingRegion.setPreferredSize(
new Dimension(sharingRegionWidth, sharingRegionHeight));
frame.pack();
if (initialFrameX > -1 && initialFrameY > -1)
frame.setLocation(initialFrameX, initialFrameY);
else
// By default we position the frame in the center of the screen.
// It's important to call this method after the pack(), because
// it requires the frame size to calculate the location.
frame.setLocationRelativeTo(null);
}
else
{
frame.pack();
// By default we position the frame in the center of the screen.
// It's important to call this method after the pack(), because
// it requires the frame size to calculate the location.
frame.setLocationRelativeTo(null);
}
return frame;
}
/**
* Adds a call listener, which listens for call ended events and would
* close any related desktop sharing frames when a call is ended.
*
* @param call the call, for which we're registering a listener
* @param frame the frame to be closed on call ended
*/
private static void addCallListener(Call call, JFrame frame)
{
OperationSetBasicTelephony telOpSet = call.getProtocolProvider()
.getOperationSet(OperationSetBasicTelephony.class);
if (telOpSet != null) // This should be always true.
{
telOpSet.addCallListener(new CallListener()
{
/**
* Implements CallListener.callEnded. Disposes the frame
* related to the ended call.
*
* @param event the <tt>CallEvent</tt> that notified us
*/
public void callEnded(CallEvent event)
{
Call call = event.getSourceCall();
JFrame desktopFrame = callDesktopFrames.get(call);
if (desktopFrame != null)
{
desktopFrame.dispose();
callDesktopFrames.remove(call);
}
}
public void incomingCallReceived(CallEvent event) {}
public void outgoingCallCreated(CallEvent event) {}
});
}
}
/**
* Adds the desktop sharing listener.
*
* @param call the call, for which we're registering a listener
* @param frame the frame to be closed on call ended
*/
private static void addDesktopSharingListener(final Call call, JFrame frame)
{
OperationSetVideoTelephony videoOpSet =
call.getProtocolProvider()
.getOperationSet(OperationSetVideoTelephony.class);
videoOpSet.addPropertyChangeListener(call, new PropertyChangeListener()
{
public void propertyChange(PropertyChangeEvent evt)
{
if (OperationSetVideoTelephony.LOCAL_VIDEO_STREAMING
.equals(evt.getPropertyName())
&& evt.getNewValue().equals(MediaDirection.RECVONLY))
{
JFrame desktopFrame = callDesktopFrames.get(call);
if (desktopFrame != null)
{
desktopFrame.dispose();
callDesktopFrames.remove(call);
}
}
}
});
}
/**
* Initializes the content pane of the given window.
*
* @param frame the parent frame
* @param initialFrame indicates if this is the frame which initiates the
* desktop sharing
*/
private static void initContentPane(JFrame frame, boolean initialFrame)
{
JPanel contentPane = new JPanel()
{
protected void paintComponent(Graphics g)
{
if (TransparentFrame.isTranslucencySupported)
{
AntialiasingManager.activateAntialiasing(g);
final int R = 240;
final int G = 240;
final int B = 240;
Paint p =
new GradientPaint(0.0f, 0.0f, new Color(R, G, B, 0),
getWidth(), getHeight(), new Color(R, G, B, 0), true);
Graphics2D g2d = (Graphics2D)g;
g2d.setPaint(p);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(new Color( Color.DARK_GRAY.getRed(),
Color.DARK_GRAY.getGreen(),
Color.DARK_GRAY.getBlue(), 180));
g2d.setStroke(
new BasicStroke((float) 4));
g2d.drawRoundRect(
0, 0, getWidth() - 1, getHeight() - 1, 20, 20);
}
else
{
super.paintComponent(g);
}
}
};
contentPane.setOpaque(false);
contentPane.setDoubleBuffered(false);
contentPane.setLayout(new BorderLayout());
contentPane.setBorder(BorderFactory.createEmptyBorder(
SHARING_REGION_INDENT, SHARING_REGION_INDENT,
SHARING_REGION_INDENT, SHARING_REGION_INDENT));
frame.setContentPane(contentPane);
if (TransparentFrame.isTranslucencySupported)
frame.setAlwaysOnTop(true);
}
/**
* Creates and initializes the button panel.
*
* @param frame the parent frame
* @param sharingRegion the sharing region component
* @param initialFrame indicates if this is the frame which initiates the
* desktop sharing
* @param call the current call, if we're in a call
* @param protocolProvider the protocol provider
* @param contact the contact, which is the receiver of the call
*
* @return the created button panel
*/
private static JPanel initButtons(
final JFrame frame,
final JComponent sharingRegion,
boolean initialFrame,
final Call call,
final ProtocolProviderService protocolProvider,
final String contact)
{
JPanel buttonPanel = new TransparentPanel(new GridBagLayout())
{
public void paintComponent(Graphics g)
{
if (!TransparentFrame.isTranslucencySupported)
{
super.paintComponent(g);
return;
}
Graphics2D g2d = (Graphics2D) g.create();
AntialiasingManager.activateAntialiasing(g2d);
g2d.setColor(new Color( Color.DARK_GRAY.getRed(),
Color.DARK_GRAY.getGreen(),
Color.DARK_GRAY.getBlue(), 180));
GeneralPath shape = new GeneralPath();
int x = -SHARING_REGION_INDENT + 2;
int y = 0;
int width = getWidth() + SHARING_REGION_INDENT*2 - 4;
int height = getHeight() + SHARING_REGION_INDENT*2 - 2;
shape.moveTo(x, y);
shape.lineTo(width, y);
shape.lineTo(width, height - 12);
shape.curveTo(width, height - 12,
width, height,
width - 12, height);
shape.lineTo(12, height);
shape.curveTo(12, height,
x, height,
x, height - 12);
shape.lineTo(x, y);
shape.closePath();
g2d.fill(shape);
g2d.setColor(getBackground());
}
};
GridBagConstraints constraints = new GridBagConstraints();
buttonPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
buttonPanel.setPreferredSize(
new Dimension(sharingRegion.getWidth(), 30));
if (initialFrame)
{
JButton startButton = createButton(
GuiActivator.getResources()
.getI18NString("service.gui.START_SHARING"));
JButton cancelButton = createButton(
GuiActivator.getResources()
.getI18NString("service.gui.CANCEL"));
constraints.gridx = 0;
constraints.gridy = 0;
constraints.weightx = 1.0;
constraints.insets = new Insets(0, 0, 0, 5);
constraints.anchor = GridBagConstraints.EAST;
buttonPanel.add(cancelButton, constraints);
constraints.gridx = 1;
constraints.gridy = 0;
constraints.weightx = 1.0;
constraints.anchor = GridBagConstraints.WEST;
buttonPanel.add(startButton, constraints);
constraints.gridx = 3;
constraints.gridy = 0;
constraints.weightx = 0;
constraints.insets = new Insets(0, 0, 2, 2);
constraints.anchor = GridBagConstraints.SOUTHWEST;
buttonPanel.add(
createResizeLabel(frame, sharingRegion, buttonPanel),
constraints);
startButton.setCursor(Cursor.getDefaultCursor());
cancelButton.setCursor(Cursor.getDefaultCursor());
cancelButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
frame.dispose();
}
});
startButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Point location = sharingRegion.getLocationOnScreen();
initialFrameX = frame.getX();
initialFrameY = frame.getY();
sharingRegionWidth = sharingRegion.getWidth();
sharingRegionHeight = sharingRegion.getHeight();
frame.dispose();
if (call != null)
CallManager.enableRegionDesktopSharing(
call, location.x, location.y,
sharingRegionWidth, sharingRegionHeight);
else
CallManager.createRegionDesktopSharing(
protocolProvider, contact,
location.x, location.y,
sharingRegionWidth, sharingRegionHeight);
}
});
}
else
{
JButton stopButton = createButton(
GuiActivator.getResources()
.getI18NString("service.gui.STOP_SHARING"));
buttonPanel.add(stopButton);
stopButton.setCursor(Cursor.getDefaultCursor());
stopButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if (call != null)
CallManager.enableDesktopSharing(call, false);
frame.dispose();
}
});
}
return buttonPanel;
}
/**
* Creates a button with the given text.
*
* @param text the text of the button
* @return the created button
*/
private static JButton createButton(String text)
{
JButton button = new JButton(text);
button.setOpaque(false);
return button;
}
/**
* Creates the label allowing to resize the given frame.
*
* @param frame the frame to resize
* @param sharingRegion the sharing region
* @param buttonPanel the button panel, where the created label would be
* added
* @return the created resize label
*/
private static JLabel createResizeLabel(final JFrame frame,
final JComponent sharingRegion,
final JComponent buttonPanel)
{
final JLabel resizeLabel = new JLabel(resizeIcon);
resizeLabel.addMouseMotionListener(new MouseMotionAdapter()
{
public void mouseDragged(MouseEvent e)
{
Point p = e.getLocationOnScreen();
Point regionLocation = sharingRegion.getLocationOnScreen();
int sharingWidth = (int) ( p.getX()
- regionLocation.getX()
- 2*SHARING_REGION_INDENT);
int newSharingHeight = (int) (p.getY()
- frame.getY()
- buttonPanel.getHeight()
- 2*SHARING_REGION_INDENT);
// We should make sure that the width on MacOSX is a multiple
// of 16.
if (OSUtils.IS_MAC && sharingWidth%16 > 0)
sharingWidth = sharingWidth - sharingWidth%16;
sharingRegion.setPreferredSize(
new Dimension(sharingWidth, newSharingHeight));
frame.validate();
int height = (int) (p.getY() - frame.getY());
frame.setSize(sharingWidth + 2*SHARING_REGION_INDENT, height);
}
});
return resizeLabel;
}
/**
* Adds a listener for the given frame and call
*
* @param call the underlying call
* @param frame the frame to which the listener would be added
* @param sharingRegion the sharing region
*/
private static void addFrameListener( final Call call,
final JFrame frame,
final Component sharingRegion)
{
frame.addComponentListener(new ComponentListener()
{
public void componentResized(ComponentEvent e) {}
public void componentMoved(ComponentEvent e)
{
OperationSetDesktopSharingServer desktopOpSet
= call.getProtocolProvider().getOperationSet(
OperationSetDesktopSharingServer.class);
if (desktopOpSet == null)
return;
Point location = new Point( sharingRegion.getX(),
sharingRegion.getY());
SwingUtilities.convertPointToScreen(location,
frame.getContentPane());
desktopOpSet.movePartialDesktopStreaming(
call, location.x, location.y);
}
public void componentShown(ComponentEvent e) {}
public void componentHidden(ComponentEvent arg0) {}
});
}
}

@ -26,6 +26,7 @@
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.skin.*;
import net.java.sip.communicator.util.swing.*;
import net.java.sip.communicator.util.swing.transparent.*;
/**
* The <tt>OneToOneCallPeerPanel</tt> is the panel containing data for a call
@ -488,6 +489,15 @@ else if (event.getNewValue().equals(MediaDirection.SENDRECV))
if (CallManager.isDesktopSharingEnabled(call))
{
callContainer.setDesktopSharingButtonSelected(true);
if (CallManager.isRegionDesktopSharingEnabled(call))
{
TransparentFrame frame
= DesktopSharingFrame.createTransparentFrame(
call, false);
frame.setVisible(true);
}
}
else if (CallManager.isLocalVideoEnabled(call))
{
@ -1595,24 +1605,12 @@ public void mouseDragged(MouseEvent event)
}
}
/**
* {@inheritDoc}
*/
public void mouseMoved(MouseEvent event) {}
/**
* {@inheritDoc}
*/
public void mouseClicked(MouseEvent event) {}
/**
* {@inheritDoc}
*/
public void mouseEntered(MouseEvent event) {}
/**
* {@inheritDoc}
*/
public void mouseExited(MouseEvent event) {}
/**
@ -1643,34 +1641,20 @@ public void mouseReleased(MouseEvent event)
if (!closeButton.isVisible())
{
Component c = (Component) event.getSource();
closeButton.setLocation(
c.getX() + c.getWidth() - closeButton.getWidth() - 3,
closeButton.setLocation(
c.getX() + c.getWidth() - closeButton.getWidth() - 3,
c.getY() + 3);
closeButton.setVisible(true);
}
}
}
/**
* The local video close button.
*/
private class CloseButton
extends Label
implements MouseListener
{
/**
* Serial version UID.
*/
private static final long serialVersionUID = 0L;
/**
* Background image.
*/
Image image = ImageLoader.getImage(ImageLoader.CLOSE_VIDEO);
/**
* Constructor.
*/
public CloseButton()
{
int buttonWidth = image.getWidth(this) + 5;
@ -1682,9 +1666,6 @@ public CloseButton()
this.addMouseListener(this);
}
/**
* {@inheritDoc}
*/
public void paint(Graphics g)
{
g.setColor(Color.GRAY);
@ -1694,9 +1675,6 @@ public void paint(Graphics g)
getHeight()/2 - image.getHeight(this)/2, this);
}
/**
* {@inheritDoc}
*/
public void mouseClicked(MouseEvent event)
{
setLocalVideoVisible(false);
@ -1705,24 +1683,12 @@ public void mouseClicked(MouseEvent event)
.setShowHideVideoButtonSelected(false);
}
/**
* {@inheritDoc}
*/
public void mouseEntered(MouseEvent event) {}
/**
* {@inheritDoc}
*/
public void mouseExited(MouseEvent event) {}
/**
* {@inheritDoc}
*/
public void mousePressed(MouseEvent event) {}
/**
* {@inheritDoc}
*/
public void mouseReleased(MouseEvent event) {}
}
@ -1781,19 +1747,6 @@ public void setLocalVideoVisible(boolean isVisible)
.setShowHideVideoButtonSelected(isVisible);
}
if(localVideo == null && isVisible)
{
/* create local visual component if not already created */
try
{
videoTelephony.createLocalVisualComponent(callPeer,
null);
}
catch(OperationFailedException e)
{
}
}
int videoContainerCount;
if ((videoTelephony != null)
@ -1804,12 +1757,28 @@ public void setLocalVideoVisible(boolean isVisible)
if (localVideo != null)
{
videoContainer.remove(localVideo);
videoContainer.remove(closeButton);
/* release resources */
videoTelephony.disposeLocalVisualComponent(callPeer,
localVideo);
localVideo = null;
if (isVisible)
{
Container parent = localVideo.getParent();
if (parent != null)
{
parent.remove(parent);
parent.remove(closeButton);
}
videoContainer.add(
closeButton, VideoLayout.CLOSE_LOCAL_BUTTON, 0);
videoContainer.add(localVideo, VideoLayout.LOCAL, 1);
}
else
{
if (localVideo != null)
{
videoContainer.remove(localVideo);
videoContainer.remove(closeButton);
}
}
}
}
}

@ -17,7 +17,6 @@
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.neomedia.device.*;
import net.java.sip.communicator.service.neomedia.format.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.*;
@ -65,54 +64,9 @@ public class SelectScreenDialog
private static MediaDevice videoDeviceInPreview;
/**
* The parent call for which the screen is selected, if any.
* The selected media device.
*/
private Call call;
/**
* The protocol provider through which we make the sharing.
*/
private ProtocolProviderService protocolProvider;
/**
* The contact with which we'd like to share our desktop.
*/
private String contact;
/**
* Creates an instance of <tt>SelectScreenDialog</tt> by specifying the list
* of possible desktop devices to choose from.
*
* @param call the call, for which screen for desktop sharing is selected
* @param desktopDevices the list of possible desktop devices to choose
* from
*/
public SelectScreenDialog(Call call, List<MediaDevice> desktopDevices)
{
this(desktopDevices);
this.call = call;
}
/**
* Creates an instance of <tt>SelectScreenDialog</tt> by specifying the list
* of possible desktop devices to choose from.
*
* @param protocolProvider the protocol provider through which we make the
* sharing
* @param contact the contact to share the desktop with
* @param desktopDevices the list of possible desktop devices to choose
* from
*/
public SelectScreenDialog( ProtocolProviderService protocolProvider,
String contact,
List<MediaDevice> desktopDevices)
{
this(desktopDevices);
this.protocolProvider = protocolProvider;
this.contact = contact;
}
private MediaDevice selectedDevice;
/**
* Creates an instance of <tt>SelectScreenDialog</tt> by specifying the list
@ -123,6 +77,8 @@ public SelectScreenDialog( ProtocolProviderService protocolProvider,
*/
public SelectScreenDialog(List<MediaDevice> desktopDevices)
{
setModal(true);
setPreferredSize(new Dimension(400, 300));
Container contentPane = getContentPane();
@ -138,6 +94,16 @@ public SelectScreenDialog(List<MediaDevice> desktopDevices)
contentPane.add(createButtonsPanel(), BorderLayout.SOUTH);
}
/**
* Returns the selected device.
*
* @return the selected device
*/
public MediaDevice getSelectedDevice()
{
return selectedDevice;
}
/**
* Creates the buttons panel.
*
@ -155,17 +121,10 @@ private Component createButtonsPanel()
{
public void actionPerformed(ActionEvent e)
{
MediaDevice selectedDevice
selectedDevice
= (MediaDevice) deviceComboBox.getSelectedItem();
dispose();
if (call != null)
CallManager.enableDesktopSharing(call, selectedDevice, true);
else
CallManager.createDesktopSharing( protocolProvider,
contact,
selectedDevice);
}
});

@ -1161,24 +1161,7 @@ else if (desktopContacts.size() > 1)
private void shareDesktop( ProtocolProviderService protocolProvider,
String contactName)
{
MediaService mediaService = GuiActivator.getMediaService();
List<MediaDevice> desktopDevices = mediaService.getDevices(
MediaType.VIDEO, MediaUseCase.DESKTOP);
int deviceNumber = desktopDevices.size();
if (deviceNumber == 1)
CallManager.createDesktopSharing(protocolProvider, contactName);
else if (deviceNumber > 1)
{
SelectScreenDialog selectDialog
= new SelectScreenDialog( protocolProvider,
contactName,
desktopDevices);
selectDialog.setVisible(true);
}
CallManager.createDesktopSharing(protocolProvider, contactName);
}
/**

@ -122,18 +122,28 @@ public class MetaContactRightButtonMenu
"service.gui.VIDEO_CALL"));
/**
* The desktop sharing menu item.
* The menu responsible for desktop sharing when a single desktop sharing
* contact is available.
*/
private final JMenuItem desktopSharingItem = new JMenuItem(
private final SIPCommMenu contactDesktopSharingMenu = new SIPCommMenu(
GuiActivator.getResources().getI18NString(
"service.gui.SHARE_DESKTOP"));
/**
* The menu responsible for calling a contact with video.
* The menu responsible for full screen sharing when more than one contact
* is available for sharing.
*/
private final SIPCommMenu desktopSharingMenu = new SIPCommMenu(
private final SIPCommMenu multiContactFullShareMenu = new SIPCommMenu(
GuiActivator.getResources().getI18NString(
"service.gui.SHARE_DESKTOP"));
"service.gui.SHARE_FULL_SCREEN"));
/**
* The menu responsible for region screen sharing when more than one contact
* is available for sharing.
*/
private final SIPCommMenu multiContactRegionShareMenu = new SIPCommMenu(
GuiActivator.getResources().getI18NString(
"service.gui.SHARE_REGION"));
/**
* The send message menu item.
@ -201,9 +211,14 @@ public class MetaContactRightButtonMenu
private static final String videoCallPrefix = "videoCall:";
/**
* The prefix for video call contact menu.
* The prefix for full screen desktop sharing menu.
*/
private static final String desktopSharingPrefix = "desktopSharing:";
private static final String fullDesktopSharingPrefix = "shareFullScreen:";
/**
* The prefix for region screen desktop sharing menu.
*/
private static final String regionDesktopSharingPrefix = "shareRegionScreen:";
/**
* The contact to move when the move menu has been chosen.
@ -367,9 +382,16 @@ private void init()
hasContactCapabilities(contact,
OperationSetDesktopSharingServer.class))
{
desktopSharingMenu.add(
multiContactFullShareMenu.add(
createMenuItem( contactDisplayName,
desktopSharingPrefix
fullDesktopSharingPrefix
+ contact.getAddress()
+ protocolProvider.getProtocolName(),
protocolIcon));
multiContactRegionShareMenu.add(
createMenuItem( contactDisplayName,
regionDesktopSharingPrefix
+ contact.getAddress()
+ protocolProvider.getProtocolName(),
protocolIcon));
@ -402,54 +424,69 @@ private void init()
this.videoCallItem.addActionListener(this);
}
if (desktopSharingMenu.getItemCount() > 1)
if (multiContactFullShareMenu.getItemCount() > 1)
{
this.add(desktopSharingMenu);
add(multiContactFullShareMenu);
add(multiContactRegionShareMenu);
multiContactRegionShareMenu.setEnabled(false);
}
else
{
this.add(desktopSharingItem);
this.desktopSharingItem.setName("desktopSharing");
this.desktopSharingItem.addActionListener(this);
// Create desktop sharing menu.
contactDesktopSharingMenu.add(
createMenuItem( GuiActivator.getResources()
.getI18NString("service.gui.SHARE_FULL_SCREEN"),
"shareFullScreen",
null));
JMenuItem menuItem = createMenuItem( GuiActivator.getResources()
.getI18NString("service.gui.SHARE_REGION"),
"shareRegion",
null);
menuItem.setEnabled(false);
contactDesktopSharingMenu.add(menuItem);
add(contactDesktopSharingMenu);
}
this.add(sendFileItem);
add(sendFileItem);
this.addSeparator();
addSeparator();
this.add(moveToMenu);
this.add(moveSubcontactMenu);
add(moveToMenu);
add(moveSubcontactMenu);
this.addSeparator();
addSeparator();
this.add(addContactItem);
add(addContactItem);
this.addSeparator();
addSeparator();
this.add(removeContactMenu);
this.add(renameContactItem);
add(removeContactMenu);
add(renameContactItem);
this.addSeparator();
addSeparator();
this.add(viewHistoryItem);
add(viewHistoryItem);
this.initPluginComponents();
initPluginComponents();
this.sendMessageItem.setName("sendMessage");
sendMessageItem.setName("sendMessage");
this.sendSmsItem.setName("sendSms");
this.sendFileItem.setName("sendFile");
this.moveToMenu.setName("moveToGroup");
this.addContactItem.setName("addContact");
this.renameContactItem.setName("renameContact");
this.viewHistoryItem.setName("viewHistory");
sendSmsItem.setName("sendSms");
sendFileItem.setName("sendFile");
moveToMenu.setName("moveToGroup");
addContactItem.setName("addContact");
renameContactItem.setName("renameContact");
viewHistoryItem.setName("viewHistory");
this.sendMessageItem.addActionListener(this);
this.sendSmsItem.addActionListener(this);
this.sendFileItem.addActionListener(this);
this.renameContactItem.addActionListener(this);
this.viewHistoryItem.addActionListener(this);
this.addContactItem.addActionListener(this);
sendMessageItem.addActionListener(this);
sendSmsItem.addActionListener(this);
sendFileItem.addActionListener(this);
renameContactItem.addActionListener(this);
viewHistoryItem.addActionListener(this);
addContactItem.addActionListener(this);
// Disable all menu items that do nothing.
if (metaContact.getDefaultContact(
@ -466,7 +503,7 @@ private void init()
if (metaContact.getDefaultContact(
OperationSetDesktopSharingServer.class) == null)
this.desktopSharingItem.setEnabled(false);
this.contactDesktopSharingMenu.setEnabled(false);
if (metaContact.getDefaultContact(
OperationSetBasicInstantMessaging.class) == null)
@ -577,13 +614,13 @@ private void initMnemonics()
char desktopSharingMnemonic = GuiActivator.getResources()
.getI18nMnemonic("service.gui.SHARE_DESKTOP");
if (desktopSharingMenu.getItemCount() > 1)
if (contactDesktopSharingMenu.getItemCount() > 1)
{
this.desktopSharingMenu.setMnemonic(desktopSharingMnemonic);
this.contactDesktopSharingMenu.setMnemonic(desktopSharingMnemonic);
}
else
{
this.desktopSharingItem.setMnemonic(desktopSharingMnemonic);
this.contactDesktopSharingMenu.setMnemonic(desktopSharingMnemonic);
}
this.sendSmsItem.setMnemonic(GuiActivator.getResources()
.getI18nMnemonic("service.gui.SEND_SMS"));
@ -650,7 +687,7 @@ else if (itemName.equals("videoCall"))
CallManager.createVideoCall(
contact.getProtocolProvider(), contact.getAddress());
}
else if (itemName.equals("desktopSharing"))
else if (itemName.equals("shareFullScreen"))
{
contact = metaContact.getDefaultContact(
OperationSetVideoTelephony.class);
@ -658,6 +695,14 @@ else if (itemName.equals("desktopSharing"))
CallManager.createDesktopSharing(
contact.getProtocolProvider(), contact.getAddress());
}
else if (itemName.equals("shareRegion"))
{
contact = metaContact.getDefaultContact(
OperationSetVideoTelephony.class);
CallManager.createRegionDesktopSharing(
contact.getProtocolProvider(), contact.getAddress());
}
else if (itemName.equals("sendFile"))
{
SipCommFileChooser scfc = GenericFileDialog.create(
@ -791,14 +836,23 @@ else if (itemName.startsWith(videoCallPrefix))
CallManager.createVideoCall(contact.getProtocolProvider(),
contact.getAddress());
}
else if (itemName.startsWith(desktopSharingPrefix))
else if (itemName.startsWith(fullDesktopSharingPrefix))
{
contact = getContactFromMetaContact(
itemName.substring(desktopSharingPrefix.length()));
itemName.substring(fullDesktopSharingPrefix.length()));
CallManager.createDesktopSharing( contact.getProtocolProvider(),
contact.getAddress());
}
else if (itemName.startsWith(regionDesktopSharingPrefix))
{
contact = getContactFromMetaContact(
itemName.substring(regionDesktopSharingPrefix.length()));
CallManager.createRegionDesktopSharing(
contact.getProtocolProvider(),
contact.getAddress());
}
}
/**
@ -993,7 +1047,7 @@ public void loadSkin()
videoCallItem.setIcon(new ImageIcon(
ImageLoader.getImage(ImageLoader.VIDEO_CALL)));
desktopSharingItem.setIcon(new ImageIcon(
contactDesktopSharingMenu.setIcon(new ImageIcon(
ImageLoader.getImage(ImageLoader.DESKTOP_SHARING)));
sendMessageItem.setIcon(new ImageIcon(

@ -42,6 +42,7 @@ Import-Package: org.osgi.framework,
net.java.sip.communicator.util.swing.event,
net.java.sip.communicator.util.swing.plaf,
net.java.sip.communicator.util.skin,
net.java.sip.communicator.util.swing.transparent,
javax.accessibility,
javax.imageio,
javax.swing,

@ -905,6 +905,12 @@ public class ImageLoader
public static final ImageID VOLUME_CONTROL_BUTTON
= new ImageID("service.gui.buttons.VOLUME_CONTROL");
/**
* The transparent window button background.
*/
public static final ImageID TRANSPARENT_WINDOW_BUTTON
= new ImageID("service.gui.buttons.TRANSPARENT_WINDOW_BUTTON");
/*
* =======================================================================
* ------------------------ EDIT TOOLBAR ICONS ---------------------------

@ -0,0 +1,170 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*
* Based on the code of Anthony Petrov
* http://java.sun.com/developer/technicalArticles/GUI/translucent_shaped_windows/
*/
package net.java.sip.communicator.util.swing.transparent;
import java.awt.GraphicsConfiguration;
import java.awt.Shape;
import java.awt.Window;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Yana Stamcheva
*/
public class AWTUtilitiesWrapper
{
private static Class<?> awtUtilitiesClass;
private static Class<?> translucencyClass;
private static Method mIsTranslucencySupported, mIsTranslucencyCapable,
mSetWindowShape, mSetWindowOpacity, mSetWindowOpaque;
public static Object PERPIXEL_TRANSPARENT, TRANSLUCENT, PERPIXEL_TRANSLUCENT;
static void init()
{
try
{
awtUtilitiesClass = Class.forName("com.sun.awt.AWTUtilities");
translucencyClass
= Class.forName("com.sun.awt.AWTUtilities$Translucency");
if (translucencyClass.isEnum())
{
Object[] kinds = translucencyClass.getEnumConstants();
if (kinds != null)
{
PERPIXEL_TRANSPARENT = kinds[0];
TRANSLUCENT = kinds[1];
PERPIXEL_TRANSLUCENT = kinds[2];
}
}
mIsTranslucencySupported = awtUtilitiesClass.getMethod(
"isTranslucencySupported", translucencyClass);
mIsTranslucencyCapable = awtUtilitiesClass.getMethod(
"isTranslucencyCapable", GraphicsConfiguration.class);
mSetWindowShape = awtUtilitiesClass.getMethod(
"setWindowShape", Window.class, Shape.class);
mSetWindowOpacity = awtUtilitiesClass.getMethod(
"setWindowOpacity", Window.class, float.class);
mSetWindowOpaque = awtUtilitiesClass.getMethod(
"setWindowOpaque", Window.class, boolean.class);
}
catch (NoSuchMethodException ex)
{
Logger.getLogger(AWTUtilitiesWrapper.class.getName())
.log(Level.SEVERE, null, ex);
}
catch (SecurityException ex)
{
Logger.getLogger(AWTUtilitiesWrapper.class.getName())
.log(Level.SEVERE, null, ex);
}
catch (ClassNotFoundException ex)
{
Logger.getLogger(AWTUtilitiesWrapper.class.getName())
.log(Level.SEVERE, null, ex);
}
}
static
{
init();
}
private static boolean isSupported(Method method, Object kind)
{
if (awtUtilitiesClass == null || method == null)
{
return false;
}
try
{
Object ret = method.invoke(null, kind);
if (ret instanceof Boolean)
{
return ((Boolean)ret).booleanValue();
}
}
catch (IllegalAccessException ex)
{
Logger.getLogger(AWTUtilitiesWrapper.class.getName())
.log(Level.SEVERE, null, ex);
}
catch (IllegalArgumentException ex)
{
Logger.getLogger(AWTUtilitiesWrapper.class.getName())
.log(Level.SEVERE, null, ex);
}
catch (InvocationTargetException ex)
{
Logger.getLogger(AWTUtilitiesWrapper.class.getName())
.log(Level.SEVERE, null, ex);
}
return false;
}
public static boolean isTranslucencySupported(Object kind)
{
if (translucencyClass == null)
return false;
return isSupported(mIsTranslucencySupported, kind);
}
public static boolean isTranslucencyCapable(GraphicsConfiguration gc)
{
return isSupported(mIsTranslucencyCapable, gc);
}
private static void set(Method method, Window window, Object value)
{
if (awtUtilitiesClass == null || method == null)
{
return;
}
try
{
method.invoke(null, window, value);
}
catch (IllegalAccessException ex)
{
Logger.getLogger(AWTUtilitiesWrapper.class.getName())
.log(Level.SEVERE, null, ex);
}
catch (IllegalArgumentException ex)
{
Logger.getLogger(AWTUtilitiesWrapper.class.getName())
.log(Level.SEVERE, null, ex);
}
catch (InvocationTargetException ex)
{
Logger.getLogger(AWTUtilitiesWrapper.class.getName())
.log(Level.SEVERE, null, ex);
}
}
public static void setWindowShape(Window window, Shape shape)
{
set(mSetWindowShape, window, shape);
}
public static void setWindowOpacity(Window window, float opacity)
{
set(mSetWindowOpacity, window, Float.valueOf(opacity));
}
public static void setWindowOpaque(Window window, boolean opaque)
{
set(mSetWindowOpaque, window, Boolean.valueOf(opaque));
}
}

@ -0,0 +1,82 @@
/*
* 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.util.swing.transparent;
import java.awt.*;
import javax.swing.*;
/**
*
* @author Yana Stamcheva
*/
public class TransparentFrame
extends JFrame
implements RootPaneContainer
{
/**
* Indicates if the transparency is supported from the current graphics
* environment.
*/
public static boolean isTranslucencySupported;
/**
* Creates a transparent undecorated frame. If the transparency is not
* supported creates a normal undecorated frame.
*
* @return the created frame
*/
public static TransparentFrame createTransparentFrame()
{
isTranslucencySupported
= AWTUtilitiesWrapper.isTranslucencySupported(
AWTUtilitiesWrapper.PERPIXEL_TRANSLUCENT);
GraphicsConfiguration translucencyCapableGC
= GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration();
if (!AWTUtilitiesWrapper.isTranslucencyCapable(translucencyCapableGC))
{
translucencyCapableGC = null;
GraphicsEnvironment env
= GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] devices = env.getScreenDevices();
for (int i = 0; i < devices.length
&& translucencyCapableGC == null; i++)
{
GraphicsConfiguration[] configs = devices[i].getConfigurations();
for (int j = 0; j < configs.length
&& translucencyCapableGC == null; j++)
{
if (AWTUtilitiesWrapper.isTranslucencyCapable(configs[j]))
{
translucencyCapableGC = configs[j];
}
}
}
if (translucencyCapableGC == null)
{
isTranslucencySupported = false;
}
}
return new TransparentFrame(translucencyCapableGC);
}
/** Creates new form FancyFrame */
private TransparentFrame(GraphicsConfiguration gc)
{
super(gc);
setUndecorated(true);
AWTUtilitiesWrapper.setWindowOpaque(this, false);
AWTUtilitiesWrapper.setWindowOpacity(this, 1f);
}
}

@ -35,11 +35,13 @@ Import-Package: org.xml.sax,
net.java.sip.communicator.service.contactlist,
sun.awt.shell,
sun.net.util,
sun.net.dns
sun.net.dns,
com.sun.awt
Export-Package: net.java.sip.communicator.util.xml,
net.java.sip.communicator.util.swing.plaf,
net.java.sip.communicator.util.swing.event,
net.java.sip.communicator.util.swing,
net.java.sip.communicator.util.swing.transparent,
net.java.sip.communicator.util.swing.border,
net.java.sip.communicator.util,
net.java.sip.communicator.util.skin,

Loading…
Cancel
Save