/* * 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.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import com.motorola.studio.android.videos.i18n.VideosNLS; import com.motorola.studio.android.videos.model.Video; import com.motorola.studio.android.videos.model.VideoChannel; /** * A specialized Composite that shows all videos in a list. * The videos are organized in tabs, given that each tab represent * a different channel / playlist */ public class VideosListComposite extends Composite { /* * The channels that are being represented */ private List<VideoChannel> videoChannels = null; /* * The selected video in the list */ private String selectedVideo = null; /* * The default channel */ private String defaultVideoChannelName = null; /* * Widgets in the composite */ private final List<Composite> tabCompositeList = new ArrayList<Composite>(); // List of the parent composites for each tab private final Map<String, VideoComposite> videoCompositeMap = new HashMap<String, VideoComposite>(); // Map "video id" -> composite that represents that video private final Map<String, Composite> noVideosCompositeMap = new HashMap<String, Composite>(); // Map "channel name" -> "no videos" composite /** * Constructor responsible for creating the entire component * * @param parent the parent composite * @param style SWT style * @param videoChannels all video channels with their respective videos already populated * @param defaultVideoChannelName the name of the default video channel (to be selected in the UI) */ public VideosListComposite(Composite parent, int style, List<VideoChannel> videoChannels, String defaultVideoChannelName) { super(parent, style); this.videoChannels = videoChannels; this.defaultVideoChannelName = defaultVideoChannelName; createControls(); } /** * Change the style for the video being played * * @param video the video to be selected */ public void setSelectedVideo(Video video) { VideoComposite composite; if (video != null) { // deselect the current selected video if (selectedVideo != null) { composite = videoCompositeMap.get(selectedVideo); if (composite != null) { composite.deselect(); } } // update the selection selectedVideo = video.getId(); composite = videoCompositeMap.get(video.getId()); if (composite != null) { composite.select(); } } else { selectedVideo = null; } } /** * Highlight the given keyword in the video composites being * displayed at this moment * * @param keyword the keyword to be highlighted */ public void highlightKeywords(String keyword) { for (Map.Entry<String, VideoComposite> entry : videoCompositeMap.entrySet()) { VideoComposite videoComposite = entry.getValue(); if (videoComposite.getVideo().isVisible()) { videoComposite.highlightKeyword(keyword); } } } /** * Create all widgets of this composite */ private void createControls() { // set the composite layout setLayout(new GridLayout(1, false)); CTabFolder tabFolder = new CTabFolder(this, SWT.NONE); tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); tabFolder.setBorderVisible(true); tabFolder.setFont(new Font(getShell().getDisplay(), getShell().getDisplay().getSystemFont() .getFontData()[0].getName(), 10, SWT.BOLD)); tabCompositeList.clear(); videoCompositeMap.clear(); for (VideoChannel channel : videoChannels) { CTabItem item = new CTabItem(tabFolder, SWT.NONE); item.setText(channel.getDisplayName()); item.setData(channel); Composite itemComposite = new Composite(tabFolder, SWT.NONE); itemComposite.setLayout(new GridLayout(1, false)); itemComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Composite videosScrolledComposite = populateVideos(itemComposite, channel); // store tab item videosScrolledComposite.setData(item); tabCompositeList.add(videosScrolledComposite); item.setControl(itemComposite); if (channel.getName().equals(defaultVideoChannelName)) { tabFolder.setSelection(item); } } } /** * Populate one tab (given the parent composite) with its videos * * @param parent * @param videos */ private Composite populateVideos(Composite parent, VideoChannel channel) { /* * Create the scrolled composite */ final ScrolledComposite videosScrolledComposite = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL); videosScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); videosScrolledComposite.setLayout(new GridLayout(1, false)); /* * Create the composite which will be the parent of each video representation composite */ final Composite videosComposite = new Composite(videosScrolledComposite, SWT.NONE); videosComposite.setLayout(new GridLayout(1, false)); videosComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); createNoVideosComposite(videosComposite, channel.getName()); /* * For each video, create its composite */ for (final Video video : channel.getVideos()) { VideoComposite videoComposite = new VideoComposite(this, videosComposite, videosScrolledComposite, SWT.NONE, video); videoComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); videoCompositeMap.put(video.getId(), videoComposite); } videosScrolledComposite.setContent(videosComposite); videosScrolledComposite.setExpandVertical(true); videosScrolledComposite.setExpandHorizontal(true); videosScrolledComposite.setAlwaysShowScrollBars(true); videosScrolledComposite.getVerticalBar().setIncrement(20); videosScrolledComposite.getVerticalBar().setPageIncrement(100); videosScrolledComposite.getHorizontalBar().setIncrement(20); videosScrolledComposite.getHorizontalBar().setPageIncrement(100); videosScrolledComposite.addControlListener(new ControlAdapter() { @Override public void controlResized(ControlEvent e) { videosScrolledComposite.setMinSize(videosComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); } }); return videosScrolledComposite; } /** * Implement this */ public void sort() { /* // change all parents setParent(getSite().getShell()); // add in the order setParent(mainComposite); */ } /** * Filter the videos being displayed and show only the ones passed as parameter. * Also identify if all videos are in the list, so that the appropriate actions * are executed. * * @param videos the list of videos to remain in the screen * @param all whether all videos videos are in the list or not */ public void filter(List<Video> videos, boolean all) { /* * Hide all items */ for (Map.Entry<String, VideoComposite> composite : videoCompositeMap.entrySet()) { GridData layoutData = (GridData) composite.getValue().getLayoutData(); if (layoutData != null) { layoutData.exclude = true; } composite.getValue().setVisible(false); } /* * Show only items that match */ for (Video video : videos) { ((GridData) videoCompositeMap.get(video.getId()).getLayoutData()).exclude = false; Composite composite = videoCompositeMap.get(video.getId()); composite.setVisible(true); } /* * Update tab name accordingly, and also display or hide the * "no videos" message */ for (Composite composite : tabCompositeList) { CTabItem tabItem = (CTabItem) composite.getData(); VideoChannel videoChannel = (VideoChannel) tabItem.getData(); if (!all) { tabItem.setText(videoChannel.getDisplayName() + " (" + videoChannel.getVisibleVideos() + ")"); } else { tabItem.setText(videoChannel.getDisplayName()); } /* * Display or hide the "No Videos" composite */ if (videoChannel.getVisibleVideos() == 0) { displayNoVideosComposite(videoChannel.getName()); } else { hideNoVideosComposite(videoChannel.getName()); } // update scroll bar size ((ScrolledComposite) composite).setMinSize(composite.getChildren()[0].computeSize( SWT.DEFAULT, SWT.DEFAULT)); } // force the parent layout, as well as the layout of all children getParent().layout(true, true); } /** * Create a composite that will be displayed when no videos are * found due to a search * * @param parent the parent composite * @param channelName the channel name */ private void createNoVideosComposite(Composite parent, String channelName) { Composite noVideosComposite = new Composite(parent, SWT.NONE); GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false); layoutData.exclude = true; noVideosComposite.setLayoutData(layoutData); noVideosComposite.setLayout(new FillLayout()); noVideosComposite.setVisible(false); Label noVideosLabel = new Label(noVideosComposite, SWT.NONE); noVideosLabel.setText(VideosNLS.UI_No_Videos_Search); noVideosCompositeMap.put(channelName, noVideosComposite); } /** * Display the composite that states that no videos are * found due to a search * * @param channelName the channel name */ private void displayNoVideosComposite(String channelName) { Composite noVideosComposite = noVideosCompositeMap.get(channelName); if (noVideosComposite != null) { ((GridData) noVideosComposite.getLayoutData()).exclude = false; noVideosComposite.setVisible(true); } } /** * Hide the composite that states that no videos are * found due to a search * * @param channelName the channel name */ private void hideNoVideosComposite(String channelName) { Composite noVideosComposite = noVideosCompositeMap.get(channelName); if (noVideosComposite != null) { ((GridData) noVideosComposite.getLayoutData()).exclude = true; noVideosComposite.setVisible(false); } } }