summaryrefslogtreecommitdiff
path: root/src/plugins/videos/src/com/motorola/studio/android/videos/ui/views/VideoComposite.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/videos/src/com/motorola/studio/android/videos/ui/views/VideoComposite.java')
-rw-r--r--src/plugins/videos/src/com/motorola/studio/android/videos/ui/views/VideoComposite.java520
1 files changed, 520 insertions, 0 deletions
diff --git a/src/plugins/videos/src/com/motorola/studio/android/videos/ui/views/VideoComposite.java b/src/plugins/videos/src/com/motorola/studio/android/videos/ui/views/VideoComposite.java
new file mode 100644
index 0000000..54e9076
--- /dev/null
+++ b/src/plugins/videos/src/com/motorola/studio/android/videos/ui/views/VideoComposite.java
@@ -0,0 +1,520 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.motorola.studio.android.videos.ui.views;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+
+import com.motorola.studio.android.common.log.StudioLogger;
+import com.motorola.studio.android.videos.Activator;
+import com.motorola.studio.android.videos.i18n.VideosNLS;
+import com.motorola.studio.android.videos.model.Video;
+import com.motorola.studio.android.videos.model.VideoManager;
+import com.motorola.studio.android.videos.ui.utils.UiUtilities;
+
+/**
+ * A specialized Composite to be used to represent a single Video
+ *
+ */
+public class VideoComposite extends Composite
+{
+
+ /*
+ * Video Manager
+ */
+ private VideoManager videoManager;
+
+ /*
+ * The video that is being represented
+ */
+ private Video video = null;
+
+ /*
+ * Resource constants
+ */
+ private final String PLAY_ICON = "icons/play_icon.png";
+
+ private final String THUMBNAIL_LOADING_ICON = "icons/thumbnail_loading.png";
+
+ private final String THUMBNAIL_NOT_AVAILABLE_ICON = "icons/preview_not_available.png";
+
+ /*
+ * Other global elements and resources
+ */
+ private Image playImg = null;
+
+ private Image thumbLoadingImg = null;
+
+ private Font videoTitleFont = null;
+
+ private Font videoTitleSelectedFont = null;
+
+ private Color highlightTextColor = null;
+
+ private Color backgroundColor = null;
+
+ private boolean showAllDescription = false;
+
+ /*
+ * Some widgets in the composite
+ */
+ private StyledText videoTitle = null;
+
+ private final List<StyledText> styledTexts = new ArrayList<StyledText>();
+
+ /*
+ * Parent class
+ */
+ private VideosListComposite parentClass = null;
+
+ private final ScrolledComposite scrollParent;
+
+ /*
+ * Layout details
+ */
+ private final int MINIMUM_DESCRIPTION_COLUMN_WIDTH = 200;
+
+ /**
+ * Constructor responsible for creating the entire component
+ *
+ * @param parent the parent composite
+ * @param style SWT style
+ * @param video the video to be represented
+ */
+ public VideoComposite(VideosListComposite parentClass, Composite parent,
+ ScrolledComposite scrollParent, int style, Video video)
+ {
+ super(parent, style);
+ this.video = video;
+ this.parentClass = parentClass;
+ this.scrollParent = scrollParent;
+ init();
+ createControls();
+ }
+
+ /**
+ * Initialize variables and resources
+ */
+ private void init()
+ {
+
+ try
+ {
+
+ // Video Manager instance
+ videoManager = VideoManager.getInstance();
+
+ /*
+ * Images to be used
+ */
+ playImg =
+ new Image(getShell().getDisplay(), FileLocator.toFileURL(
+ Activator.getDefault().getBundle().getEntry(PLAY_ICON)).getPath());
+
+ thumbLoadingImg =
+ new Image(getShell().getDisplay(), FileLocator.toFileURL(
+ Activator.getDefault().getBundle().getEntry(THUMBNAIL_LOADING_ICON))
+ .getPath());
+
+ /*
+ * Fonts
+ */
+ videoTitleFont =
+ new Font(getShell().getDisplay(), getShell().getDisplay().getSystemFont()
+ .getFontData()[0].getName(), 10, SWT.BOLD);
+
+ videoTitleSelectedFont =
+ new Font(getShell().getDisplay(), getShell().getDisplay().getSystemFont()
+ .getFontData()[0].getName(), 10, SWT.BOLD | SWT.ITALIC);
+
+ /*
+ * Colors
+ */
+ backgroundColor = getShell().getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+
+ highlightTextColor = getShell().getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION);
+
+ }
+ catch (Exception e)
+ {
+ StudioLogger.error(this.getClass(), "Error while initializing Video Composite", e);
+ }
+
+ }
+
+ /**
+ * Create all widgets of this composite
+ */
+ private void createControls()
+ {
+
+ // set the composite layout
+ setLayout(new GridLayout(3, false));
+ setBackground(backgroundColor);
+
+ // Set loading thumbnail image
+ final Label videoImage = new Label(this, SWT.NONE);
+ videoImage.setImage(thumbLoadingImg);
+
+ // Get the real thumbnail
+ Thread updateVideoImage = new Thread(new Runnable()
+ {
+
+ public void run()
+ {
+ // this operation is time consuming (require internet access)
+ // that's why we are using a new thread and just after we have the
+ // file download we use the UI thread
+ final File thumbnail = videoManager.getThumbnail(video.getSnapshot());
+
+ Display.getDefault().syncExec(new Runnable()
+ {
+ public void run()
+ {
+ Image videoImg =
+ thumbnail != null ? new Image(getShell().getDisplay(), thumbnail
+ .toString()) : null;
+
+ // make sure the element still exists, the view can be closed
+ if (!videoImage.isDisposed())
+ {
+ if (videoImg != null)
+ {
+ videoImage.setImage(videoImg);
+ }
+ else
+ {
+ ImageData notAvailable =
+ Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID,
+ THUMBNAIL_NOT_AVAILABLE_ICON).getImageData();
+ Point size = videoImage.getSize();
+ if (videoImage.getImage() != null
+ && !videoImage.getImage().isDisposed())
+ {
+ size =
+ new Point(videoImage.getImage().getBounds().width,
+ videoImage.getImage().getBounds().height);
+ videoImage.getImage().dispose();
+ }
+ videoImage.setImage(new Image(getShell().getDisplay(), notAvailable
+ .scaledTo(size.x, size.y)));
+ }
+ }
+
+ }
+ });
+
+ }
+ });
+ updateVideoImage.start();
+
+ videoImage.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
+ videoImage.setBackground(backgroundColor);
+
+ final Composite titleAndDescriptionComposite =
+ new Composite(this, SWT.WRAP | SWT.BACKGROUND);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ data.widthHint = MINIMUM_DESCRIPTION_COLUMN_WIDTH;
+ data.minimumWidth = MINIMUM_DESCRIPTION_COLUMN_WIDTH;
+ data.heightHint = videoImage.getSize().y;
+ titleAndDescriptionComposite.setLayoutData(data);
+ titleAndDescriptionComposite.setLayout(new GridLayout(1, true));
+ titleAndDescriptionComposite.setBackground(backgroundColor);
+
+ videoTitle = new StyledText(titleAndDescriptionComposite, SWT.WRAP | SWT.BACKGROUND);
+ videoTitle.setEnabled(false);
+ videoTitle.setBackground(backgroundColor);
+ videoTitle.setFont(videoTitleFont);
+ data = new GridData(SWT.FILL, SWT.FILL, true, false);
+
+ videoTitle.setLayoutData(data);
+ styledTexts.add(videoTitle);
+
+ final StyledText videoDescription =
+ new StyledText(titleAndDescriptionComposite, SWT.WRAP | SWT.BACKGROUND);
+ videoDescription.setEnabled(false);
+ videoDescription.setBackground(backgroundColor);
+ data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ videoDescription.setLayoutData(data);
+ styledTexts.add(videoDescription);
+
+ Composite playButtonArea = new Composite(this, SWT.NONE);
+ GridLayout layout = new GridLayout(1, true);
+ playButtonArea.setLayoutData(new GridData(SWT.NONE, SWT.NONE, false, false));
+ playButtonArea.setLayout(layout);
+ playButtonArea.setBackground(backgroundColor);
+
+ Label playImage = new Label(playButtonArea, SWT.NONE);
+ playImage.setImage(playImg);
+ playImage.setBackground(backgroundColor);
+ playImage.setToolTipText(VideosNLS.UI_Play_Video);
+ playImage.setCursor(new Cursor(getShell().getDisplay(), SWT.CURSOR_HAND));
+ playImage.setLayoutData(new GridData(SWT.NONE, SWT.NONE, false, false));
+
+ videoTitle.setText(video.getTitle());
+ videoDescription.setText(video.getDescription());
+
+ final Label moreText = new Label(playButtonArea, SWT.WRAP | SWT.BACKGROUND);
+ moreText.addMouseListener(new MouseListener()
+ {
+
+ public void mouseUp(MouseEvent e)
+ {
+ if (!showAllDescription)
+ {
+ showAllDescription = true;
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ data.widthHint = MINIMUM_DESCRIPTION_COLUMN_WIDTH;
+ data.minimumWidth = MINIMUM_DESCRIPTION_COLUMN_WIDTH;
+ titleAndDescriptionComposite.setLayoutData(data);
+ }
+ else
+ {
+ showAllDescription = false;
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ data.widthHint = MINIMUM_DESCRIPTION_COLUMN_WIDTH;
+ data.minimumWidth = MINIMUM_DESCRIPTION_COLUMN_WIDTH;
+ data.heightHint = videoImage.getSize().y;
+ titleAndDescriptionComposite.setLayoutData(data);
+ }
+
+ // redraw everything
+ parentClass.layout();
+ ((Composite) scrollParent.getContent()).layout(true);
+ scrollParent.setMinSize(scrollParent.getContent().computeSize(SWT.DEFAULT,
+ SWT.DEFAULT));
+ }
+
+ public void mouseDown(MouseEvent e)
+ {
+ //do nothing
+ }
+
+ public void mouseDoubleClick(MouseEvent e)
+ {
+ //do nothing
+ }
+ });
+
+ titleAndDescriptionComposite.addControlListener(new ControlListener()
+ {
+
+ public void controlResized(ControlEvent e)
+ {
+ Point descriptionPreferedSize =
+ videoDescription.computeSize(titleAndDescriptionComposite.getSize().x,
+ SWT.DEFAULT);
+ Point titlePreferedSize =
+ videoTitle.computeSize(titleAndDescriptionComposite.getSize().x,
+ SWT.DEFAULT);
+
+ int preferedHeight = descriptionPreferedSize.y + titlePreferedSize.y;
+
+ if (preferedHeight + 20 > videoImage.getSize().y)
+ {
+ moreText.setCursor(new Cursor(getShell().getDisplay(), SWT.CURSOR_HAND));
+ moreText.setBackground(backgroundColor);
+ GridData data = new GridData(SWT.CENTER, SWT.TOP, false, false);
+ moreText.setLayoutData(data);
+
+ moreText.setVisible(true);
+ if (!showAllDescription)
+ {
+ moreText.setText("(+)");
+ moreText.setToolTipText(VideosNLS.UI_More);
+ }
+ else
+ {
+ moreText.setText("(-)");
+ moreText.setToolTipText(VideosNLS.UI_Less);
+ }
+ }
+ else
+ {
+ moreText.setVisible(false);
+ moreText.setCursor(new Cursor(getShell().getDisplay(), SWT.CURSOR_ARROW));
+ }
+ }
+
+ public void controlMoved(ControlEvent e)
+ {
+ // do nothing
+ }
+ });
+
+ playImage.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mouseDown(MouseEvent e)
+ {
+ Event event = new Event();
+ event.data = video;
+ parentClass.notifyListeners(MOTODEVVideosView.PLAY_LISTENER, event);
+ }
+ });
+
+ // create and set the pop-up menu for the composite and all widgets in the composite
+ setMenuForAllWidgets(this, createVideoPopupMenu());
+ }
+
+ /**
+ * Add a menu item in the video composite right-click, with options
+ * to copy the video URL
+ *
+ * @param videoComposite the video composite
+ * @param video the video being represented by the composite
+ * @return the menu
+ */
+ private Menu createVideoPopupMenu()
+ {
+
+ Menu popupMenu = new Menu(getShell(), SWT.POP_UP);
+
+ MenuItem videoUrl = new MenuItem(popupMenu, SWT.NONE);
+ videoUrl.setText(VideosNLS.UI_Copy_URL);
+ MenuItem videoEmbeddedUrl = new MenuItem(popupMenu, SWT.NONE);
+ videoEmbeddedUrl.setText(VideosNLS.UI_Copy_Embedded_URL);
+
+ videoUrl.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ copyTextToClipboard(video.getExternalLink());
+ }
+ });
+
+ videoEmbeddedUrl.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ copyTextToClipboard(video.getEmbeddedLink());
+ }
+ });
+
+ return popupMenu;
+ }
+
+ /**
+ * Recursively add the menu for all widgets
+ *
+ * @param mainComposite the main composite
+ * @param popupMenu the menu to be added to the main composite all all children widgets
+ */
+ private void setMenuForAllWidgets(Composite mainComposite, Menu popupMenu)
+ {
+
+ mainComposite.setMenu(popupMenu);
+
+ for (Control control : mainComposite.getChildren())
+ {
+ control.setMenu(popupMenu);
+ if (control instanceof Composite && ((Composite) control).getChildren().length > 0)
+ {
+ setMenuForAllWidgets((Composite) control, popupMenu);
+ }
+ }
+ }
+
+ /**
+ * Copy the selected text to clipboard
+ *
+ * @param text the text to be copied to the clipboard
+ */
+ private void copyTextToClipboard(String text)
+ {
+ Clipboard clipboard = new Clipboard(getShell().getDisplay());
+ clipboard.setContents(new Object[]
+ {
+ text
+ }, new Transfer[]
+ {
+ TextTransfer.getInstance()
+ });
+ }
+
+ /**
+ * Change the element appearance to mark it as selected
+ */
+ public void select()
+ {
+ videoTitle.setFont(videoTitleSelectedFont);
+ }
+
+ /**
+ * Change the element appearance to the default one
+ */
+ public void deselect()
+ {
+ videoTitle.setFont(videoTitleFont);
+ }
+
+ /**
+ * Highlight the given keyword in the composite
+ *
+ * @param keyword the keyword to be highlighted
+ */
+ public void highlightKeyword(String keyword)
+ {
+ for (StyledText styledText : styledTexts)
+ {
+ UiUtilities.highlightKeywords(styledText, keyword, highlightTextColor);
+ }
+ }
+
+ /**
+ * Retrieve the video being represented
+ *
+ * @return the video that is being represented
+ */
+ public Video getVideo()
+ {
+ return video;
+ }
+
+}