Click here to Skip to main content
15,881,424 members
Articles / Desktop Programming / Windows Forms

Crystal Image Toolkit: thumbnail image control and picture viewing.

Rate me:
Please Sign up or sign in to vote.
4.68/5 (21 votes)
11 May 2011LGPL37 min read 109.4K   8.3K   95  
Thumbnail and image viewing controls for Windows Forms, using C#.
#region gnu_license

/*
    Crystal Controls - C# control library containing the following tools:
        CrystalControl - base class
        CrystalGradientControl - a control that can either have a gradient background or be totally transparent.
        CrystalLabel - a homegrown label that can have a gradient or transparent background.
        CrystalPanel - a panel that can have a gradient or transparent background.
        CrystalTrackBar - a homegrown trackbar that can have a gradient or transparent background.
        CrystalToolStripTrackBar - a host for CrystalTrackBar that allows it to work in a ToolStrip.
        
        CrystalImageGridView - a control that hosts thumbnail images in a virtual grid.
        CrystalImageGridModel - a data model that holds a collection of CrystalImageItems
                                to feed to CrystalImageGridView.
        CrystalImageItem - a class that describes an Image file.
        CrystalThumbnailer - provides thumbnailing methods for images.

        CrystalCollector - a base class for a controller that links 
                            CrystalImageGridView to the CrystalImageGridModel.
        CrystalFileCollector - a controller that works on disk-based Image files.
        CrystalDesignCollector - a controller that works in Visual Studio toolbox designer.
        CrystalMemoryCollector - a controller that can be used to add images from memory.
        CrystalMemoryZipCollector - a controller that accesses images in zip files by streaming them into memory.
        CrystalZipCollector - a controller that accesses images in zip files by unpacking them.
        CrystalRarCollector - a controller that accesses images in rar files by unpacking them.

        CrystalPictureBox - a picture box control, derived from CrystalGradientControl.
        CrystalPictureShow - a control for viewing images and processing slideshows.
        CrystalComicShow - a control for viewing comic-book images in the CDisplay format.
 
    Copyright (C) 2006, 2008 Richard Guion
    Attilan Software Factory: http://www.attilan.com
    Contact: richard@attilan.com

   Version 1.0.0
        This is a work in progress: USE AT YOUR OWN RISK!  Interfaces/Methods may change!
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#endregion

using System;
using System.Drawing;
using System.Windows.Forms;
using CrystalToolkit;

namespace Attilan.Crystal.Controls
{
    /// <summary>
    /// Common states for image viewers built with Crystal Toolkit.
    /// </summary>
    public enum CrystalViewMode
    {
        /// <summary>
        /// Both the CrystalImageGridView and the CrystalPictureShow control are visible.
        /// </summary>
        SplitView = 0,
        /// <summary>
        /// Only the CrystalImageGridView is visible.
        /// </summary>
        ThumbView = 1,
        /// <summary>
        /// Only the CrystalPictureShow is visible.
        /// </summary>
        ImageView = 2,
        /// <summary>
        /// The CrystalPictureShow control is being used in Full Screen Mode.
        /// </summary>
        FullScreenView = 3,
        /// <summary>
        /// The CrystalPictureShow control is doing a SlideShow.
        /// </summary>
        SlideShowMode = 4
    }

    /// <summary>
    /// A Controller class that helps you tie the CrystalImageGridView, CrystalPictureShow,
    /// and other misc controls to create an Image Viewer application quickly.
    /// </summary>
    public class CrystalPictureShowController
    {
        #region Fields

        /// <summary>
        /// An array of floats that are used as zoom factors for the image viewer when the track bar is moved.
        /// </summary>
        private float[] _zoomFactorFloatItems = {.25f, .33f, .50f, .66f, .80f, 1f, 1.25f, 1.5f, 2.0f, 2.5f, 3.0f};

        /// <summary>
        /// An array of string values used in a combo box to display zoom factors.
        /// </summary>
        private string[] _zoomFactorStringItems = {
                                                      "25%", "33%", "50%", "66%", "80%", "100%", "125%", "150%", "200%",
                                                      "250%", "300%", "Fit"
                                                  };

        /// <summary>
        /// An array of floats that are used as zoom factors for the image grid when the track bar is moved.
        /// </summary>
        private float[] _thumbZoomFactorFloatItems = { .30f, .45f, .60f, .75f, .90f, 1.0f };

        /// <summary>
        /// Default setting for image grid thumbnail zoom when image grid is docked fully on the screen.
        /// </summary>
        private int _defaultThumbZoom = 2;

        /// <summary>
        /// Default setting for image grid thumbnail zoom, when the image viewer is in split mode.
        /// </summary>
        private int _defaultThumbSplitZoom = 1;

        /// <summary>
        /// Cached setting for thumbnail zoom in image grid, so when we switch back to view it is restored.
        /// </summary>
        private int _cachedThumbZoom;

        /// <summary>
        /// Crystal Collector object used to load and navigate through the images.
        /// </summary>
        private CrystalCollector _collector;

        /// <summary>
        /// The current image selected in the ImageGridView and in the PictureShow.
        /// </summary>
        private CrystalImageItem _currentImage = null;

        /// <summary>
        /// The CrystalImageGridView object displaying the thumbnails.
        /// </summary>
        private CrystalImageGridView _imageGridView = null;

        /// <summary>
        /// The CrystalPictureShow object displaying the selected image as well as the slideshow.
        /// </summary>
        private CrystalPictureShow _viewerMain = null;

        /// <summary>
        /// The CrystalToolStripTrackBar slider used to control the zoom factor in the PictureShow object.
        /// </summary>
        private CrystalToolStripTrackBar _zoomToolStripTrackBar = null;

        /// <summary>
        /// The CrystalToolStripTrackBar slider used to control the zoom factor for the thumbnails in image grid view.
        /// </summary>
        private CrystalToolStripTrackBar _thumbZoomToolStripTrackBar = null;

        // Toolstrip that contains the thumb zoom trackbar.
        private ToolStrip _thumbToolStrip = null;

        /// <summary>
        /// The main form hosting the ImageGridView and PictureShow objects.
        /// </summary>
        private Form _imageForm = null;

        /// <summary>
        /// The combo box used to control the zoom factor in the PictureShow object.
        /// </summary>
        private ToolStripComboBox _zoomComboBox = null;

        /// <summary>
        /// The current view mode of the hosted form.
        /// </summary>
        private CrystalViewMode _currentViewMode = CrystalViewMode.ThumbView;

        /// <summary>
        /// Toolbar button used to move to the previous image in the ImageGridView.
        /// </summary>
        private ToolStripButton _leftButton = null;

        /// <summary>
        /// Toolbar button used to move to the next image in the ImageGridView.
        /// </summary>
        private ToolStripButton _rightButton = null;

        /// <summary>
        /// Main caption to use in title bar when displaying images.
        /// </summary>
        private string _mainAppCaption = string.Empty;

        /// <summary>
        /// Internal flag indicating whether the CrystalThumbnail thread is running in the background.
        /// </summary>
        private bool _thumbnailComplete = true;

        #endregion

        #region Events

        /// <summary>
        /// EventHandler that will be called when a CrystalImageItem gets selected and displayed.
        /// </summary>
        public event EventHandler CrystalImageDisplayed;

        #endregion

        #region Properties

        /// <summary>
        /// Crystal Collector object used to load and navigate through the images.
        /// </summary>
        public CrystalCollector Collector
        {
            get { return _collector; }
            set { _collector = value; }
        }

        /// <summary>
        /// The current image selected in the ImageGridView and in the PictureShow.
        /// </summary>
        public CrystalImageItem CurrentImage
        {
            get { return _currentImage; }
            set { _currentImage = value; }
        }

        /// <summary>
        /// The CrystalImageGridView object displaying the thumbnails.
        /// </summary>
        public CrystalImageGridView ImageGridView
        {
            get { return _imageGridView; }
            set { _imageGridView = value; }
        }

        /// <summary>
        /// The CrystalPictureShow object displaying the selected image as well as the slideshow.
        /// </summary>
        public CrystalPictureShow PictureShow
        {
            get { return _viewerMain; }
            set { _viewerMain = value; }
        }

        /// <summary>
        /// Internal flag indicating whether the CrystalThumbnail thread is running in the background.
        /// </summary>
        public string MainAppCaption
        {
            get { return _mainAppCaption; }
            set { _mainAppCaption = value; }
        }

        /// <summary>
        /// The CrystalToolStripTrackBar slider used to control the zoom factor in the PictureShow object.
        /// </summary>
        public CrystalToolStripTrackBar ZoomTrackBar
        {
            get { return _zoomToolStripTrackBar; }
            set { _zoomToolStripTrackBar = value; }
        }

        /// <summary>
        /// The combo box used to control the zoom factor in the PictureShow object.
        /// </summary>
        public ToolStripComboBox ZoomComboBox
        {
            get { return _zoomComboBox; }
            set { _zoomComboBox = value; }
        }

        /// <summary>
        /// An array of floats that are used as zoom factors when the track bar is moved.
        /// </summary>
        public float[] ZoomFactorFloatItems
        {
            get { return _zoomFactorFloatItems; }
            set { _zoomFactorFloatItems = value; }
        }

        /// <summary>
        /// An array of string values used in a combo box to display zoom factors.
        /// </summary>
        public string[] ZoomFactorStringItems
        {
            get { return _zoomFactorStringItems; }
            set { _zoomFactorStringItems = value; }
        }

        /// <summary>
        /// The current view mode of the hosted form.
        /// </summary>
        public CrystalViewMode CurrentViewMode
        {
            get { return _currentViewMode; }
            set
            {
                _currentViewMode = value;

                ShowTrackerForViewMode();

                ShowThumbZoomForViewMode();
            }
        }

        /// <summary>
        /// The main form hosting the ImageGridView and PictureShow objects.
        /// </summary>
        public Form ImageForm
        {
            get { return _imageForm; }
            set { _imageForm = value; }
        }

        #endregion

        #region Event handlers

        /// <summary>
        /// Handles the CrystalImageClicked event from the ImageGridView.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">Event Arguments.</param>
        private void _imageGridView_CrystalImageClicked(object sender, EventArgs e)
        {
            CrystalImageSelectEventArgs eventArgs = (CrystalImageSelectEventArgs) e;
            DisplayImage(eventArgs.selectedImage);
        }

        /// <summary>
        /// Respond to keystroke events in the CrystalPictureShow viewer.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">Event arguments.</param>
        private void viewerMain_KeystrokeNavigation(object sender, EventArgs e)
        {
            CrystalKeystrokeEventArgs keyEventArgs = (CrystalKeystrokeEventArgs) e;
            _imageGridView.ProcessKeystroke(ref keyEventArgs.msg, keyEventArgs.keyData);
        }

        /// <summary>
        /// Respond to the form size changed event
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">Event arguments.</param>
        private void _imageForm_SizeChanged(object sender, EventArgs e)
        {
            SetScale();
        }

        /// <summary>
        /// Respond to the Form closing event.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">Event arguments.</param>
        private void _imageForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            CloseController();
        }

        /// <summary>
        /// Handles the right toolbar button for navigating through the list of images.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">Event arguments.</param>
        private void _rightButton_Click(object sender, EventArgs e)
        {
            MoveToRightImage();
        }

        /// <summary>
        /// Handles the left toolbar button for navigating through the list of images.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">Event arguments.</param>
        private void _leftButton_Click(object sender, EventArgs e)
        {
            MoveToLeftImage();
        }

        #endregion

        #region Methods

        /// <summary>
        /// Initializes the left and right toolbar buttons for previous and next navigation.
        /// </summary>
        /// <param name="leftButton">Left toolbar button.</param>
        /// <param name="rightButton">Right toolbar button.</param>
        public void InitNavButtons(ToolStripButton leftButton, ToolStripButton rightButton)
        {
            _leftButton = leftButton;
            _leftButton.Click += _leftButton_Click;

            _rightButton = rightButton;
            _rightButton.Click += _rightButton_Click;
        }

        /// <summary>
        /// Initializes the CrystalToolStripTrackBar and ToolStripComboBox objects used to control
        /// image magnification in the PictureShow object.
        /// </summary>
        /// <param name="crystalTrackBar">Toolstrip-based CrystalTrackBar object.</param>
        /// <param name="zoomComboBox">Toolstrip-based ComboBox object.</param>
        public void InitZoomControls(CrystalToolStripTrackBar crystalTrackBar,
                                     ToolStripComboBox zoomComboBox)
        {
            _zoomToolStripTrackBar = crystalTrackBar;
            _zoomComboBox = zoomComboBox;

            InitScaleCombo();
            InitTrackBar();
        }

        public void InitThumbZoomControls(CrystalToolStripTrackBar thumbTrackBar, ToolStrip thumbToolStrip)
        {
            _thumbZoomToolStripTrackBar = thumbTrackBar;
            _thumbToolStrip = thumbToolStrip;
            InitThumbTrackBar();
        }

        /// <summary>
        /// Initializes the CrystalPictureShow based viewer object.
        /// </summary>
        protected void InitEventHandlers()
        {
            _viewerMain.KeystrokeNavigation += viewerMain_KeystrokeNavigation;

            _imageGridView.CrystalImageClicked += _imageGridView_CrystalImageClicked;

            _imageForm.SizeChanged += _imageForm_SizeChanged;
            _imageForm.FormClosing += _imageForm_FormClosing;
        }

        /// <summary>
        /// Initializes the controller with the Form, CrystalImageGridView, and CrystalPictureShow objects.
        /// </summary>
        /// <param name="imageGridView">CrystalImageGridView control used to display thumbnails.</param>
        /// <param name="pictureShowViewer">CrystalPictureShow used to display selected images and slideshows.</param>
        /// <param name="imageForm">The main Form object that contains both the CrystalImageGridView and CrystalPictureShow controls.</param>
        public virtual void InitController(CrystalImageGridView imageGridView,
                                           CrystalPictureShow pictureShowViewer,
                                           Form imageForm)
        {
            _cachedThumbZoom = _defaultThumbZoom;

            _imageGridView = imageGridView;
            _viewerMain = pictureShowViewer;

            _imageForm = imageForm;

            SetFitImage();

            InitEventHandlers();

            _imageGridView.Focus();
        }

        /// <summary>
        /// Creates the CrystalCollector object based on the source path.
        /// </summary>
        /// <param name="sourcePath">Complete source path to the folder or file being opened.</param>
        /// <returns>Object derived from CrystalCollector</returns>
        public virtual CrystalCollector CreateCollector(string sourcePath)
        {
            CrystalCollector returnCollector = CrystalCollectorFactory.DefaultFactory.CreateCollector(sourcePath);

            return returnCollector;
        }

        /// <summary>
        /// Initialize the Crystal collector object.
        /// </summary>
        /// <param name="sourcePath">Source folder path where images files are located.</param>
        /// <returns>True if collect images was started properly, false otherwise.</returns>
        public virtual bool InitCollector(string sourcePath)
        {
            // Clear the main picture box.
            SetNullImage();

            if (_collector != null)
            {
                // Stop the thumbnailer if it is currently running in the background.
                _collector.ThumbnailComplete -= _collector_ThumbnailComplete;
                StopThumbnailer();
                _collector.Dispose();
            }

            // Add the CrystalImageGridView object to the collector.
            // The collector will work with the view to draw the images.
            _collector = CreateCollector(sourcePath);
            _collector.SetupView(_imageGridView);
            _thumbnailComplete = false;

            // Let's subscribe to the thumbnail complete event,
            // so we will know when then background thumbnail task is done.
            _collector.ThumbnailComplete += _collector_ThumbnailComplete;

            // Collect the images in the ImageLocation folder.
            return _collector.CollectImages();
        }

        /// <summary>
        /// Initialize the Crystal collector object.
        /// </summary>
        /// <param name="sourcePath">Source folder path where images files are located.</param>
        /// <param name="initialImageIndex">Image index to select in the grid.</param>
        /// <returns>True if collect images was started properly, false otherwise.</returns>
        public virtual bool InitCollector(string sourcePath, int initialImageIndex)
        {
            if (InitCollector(sourcePath))
            {
                // Select the indexed image
                InitInitialImage(initialImageIndex, true);

                return true;
            }

            return false;
        }

        /// <summary>
        /// Deals with the ThumbnailComplete event from the CrystalCollector.
        /// </summary>
        protected virtual void ThumbnailingComplete()
        {
            _thumbnailComplete = true;
        }

        /// <summary>
        /// Deals with the ThumbnailComplete event from the CrystalCollector.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">Event arguments.</param>
        private void _collector_ThumbnailComplete(object sender, EventArgs e)
        {
            ThumbnailingComplete();
        }

        /// <summary>
        /// Shuts down this controller.
        /// </summary>
        protected virtual void CloseController()
        {
            if (Collector != null)
            {
                Collector.Dispose();
            }
        }

        /// <summary>
        /// Stop the thumbnailer by killing the collection thread.
        /// </summary>
        public void StopThumbnailer()
        {
            if (!IsControllerInitialized())
                return;

            if ((_collector != null) && (!_thumbnailComplete))
            {
                _collector.StopCollection();

                _thumbnailComplete = true;
            }
        }

        /// <summary>
        /// Delegate used to initialize an image in the CrystalImageGridView.
        /// </summary>
        /// <param name="index">Index of the item to select in the CrystalCollector.</param>
        private delegate void InitInitialImageDelegate(int index);

        /// <summary>
        /// Selects the initial image in the image grid view.
        /// </summary>
        /// <param name="index">Index of the item to select in the grid.</param>
        /// <param name="ignoreGroupHeader">True means skip the group header to select the first image item.</param>
        public void InitInitialImage(int index, bool ignoreGroupHeader)
        {
            _imageForm.Invoke(new MethodInvoker(delegate
             {
                 InitInitialImageImp(index, ignoreGroupHeader);
             }));
            /*
            if (!ImageGridView.InvokeRequired)
            {
                ImageGridView.BeginInvoke(new MethodInvoker(delegate
                                                                {
                                                                    InitInitialImageImp(index, ignoreGroupHeader);
                                                                }));
            }
            else
            {
                InitInitialImageImp(index, ignoreGroupHeader);
            }
             */
        }

        /// <summary>
        /// Implementation of code block to initialized the initial image in the grid view.
        /// </summary>
        /// <param name="index">Index of the first image item.</param>
        /// <param name="ignoreGroupHeader">True means skip the group header to select the first image item.</param>
        protected virtual void InitInitialImageImp(int index, bool ignoreGroupHeader)
        {
            if (!IsControllerInitialized())
                return;

            if (ignoreGroupHeader)
                index = _collector.GridModel.NextNonHeaderIndex(index);

            if (index > -1)
            {
                CrystalImageItem theImage = _collector.GridModel[index];
                _imageGridView.SelectImage(theImage);
            }
        }

        /// <summary>
        /// Updates subscribers about the current image being displayed in the viewer.
        /// </summary>
        protected virtual void UpdateDisplaySubscribers()
        {
            if (CrystalImageDisplayed != null)
            {
                CrystalImageSelectEventArgs eventArgs = new CrystalImageSelectEventArgs(CurrentImage);
                eventArgs.MultiSelect = false;

                int startIndex = GetSelectedItemIndex();
                eventArgs.StartIndex = startIndex;
                eventArgs.EndIndex = startIndex;

                if (CrystalImageDisplayed.Target is Control)
                {
                    ((Control) (CrystalImageDisplayed.Target)).Invoke(CrystalImageDisplayed,
                                                                      new object[] {this, eventArgs});
                }
                else
                {
                    CrystalImageDisplayed(this, eventArgs);
                }
            }
        }

        /// <summary>
        /// Centers the given CrystalImageItem object within the ImageGridView.  
        /// </summary>
        /// <param name="imageItem">CrystalImageItem to center in the grid; it must exist in the GridController/GridModel of the view.</param>
        public virtual void CenterImage(CrystalImageItem imageItem)
        {
            if (!IsControllerInitialized())
                return;

            if (imageItem == null)
                return;

            ImageGridView.CenterCrystalImage(imageItem);
        }

        /// <summary>
        /// Centers the currently selected image within the ImageGridView.
        /// </summary>
        public virtual void CenterCurrentImage()
        {
            if (!IsControllerInitialized())
                return;

            CenterImage(CurrentImage);
        }

        /// <summary>
        /// Displays the given image in the CrystalPictureShow control.
        /// </summary>
        /// <param name="imageItem">CrystalImageItem object.</param>
        public virtual bool DisplayImage(CrystalImageItem imageItem)
        {
            if (!IsControllerInitialized())
                return false;

            if ((imageItem == null) || (!imageItem.Selected))
            {
                SetNullImage();
                UpdateDisplaySubscribers();
                return false;
            }

            // Detect corrupted images.
            if (imageItem.ImageCorrupted)
            {
                string message = string.Format(StringResources.CORRUPT_IMAGE_SELECTED, imageItem.DisplayName);
                MessageBox.Show(message, StringResources.CORRUPT_IMAGE_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error);

                return false;
            }

            if ((imageItem != CurrentImage) && (_collector.LoadImage(ref imageItem)))
            {
                if (CurrentImage != null)
                    CurrentImage.FullImage = null;

                CurrentImage = imageItem;

                //_viewerMain.Image = imageItem.FullImage;
                CrystalImageDisplayInfo imageInfo = new CrystalImageDisplayInfo(imageItem.FullImage, imageItem.ImageName);

                _imageForm.Invoke(new MethodInvoker(delegate
                 {
                     _viewerMain.SetImageInfo(imageInfo);
                     _viewerMain.ToolTipText = imageItem.ToolTipText;

                     SetScale();

                     if (!string.IsNullOrEmpty(MainAppCaption))
                     {
                         _imageForm.Text = MainAppCaption;
                         _imageForm.Text += " - ";
                         _imageForm.Text += imageItem.ImageName;
                     }

                     _zoomComboBox.Enabled = true;
                     _zoomToolStripTrackBar.Enabled = true;
                     EnableNavButtons();
                 }));

                UpdateDisplaySubscribers();

                return true;
            }                

            return false;
        }

        /// <summary>
        /// Allows the user to browse to a new image folder location.
        /// </summary>
        public void OpenImageFolder()
        {
            if (!IsControllerInitialized())
                return;

            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();

            // Browse for a new image folder and set this into the CrystalFileCollector.
            folderBrowserDialog.SelectedPath = _collector.ImageLocation;
            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                InitCollector(folderBrowserDialog.SelectedPath);
            }
        }

        /// <summary>
        /// Returns the index for the item currently focused in the grid view.
        /// </summary>
        /// <returns>Integer index.</returns>
        public int GetSelectedItemIndex()
        {
            if (_currentImage == null)
                return -1;

            if ((_collector != null) && (_collector.GridModel != null))
            {
                return _collector.GridModel.GetImageIndex(_currentImage);
            }

            return -1;
        }

        /// <summary>
        /// Determines if the SlideShow can start by examing the CrystalCollector object.
        /// </summary>
        /// <returns>True if the SlideShow can be started, false otherwise.</returns>
        public bool CanStartSlideShow()
        {
            if (!IsControllerInitialized())
                return false;

            if ((_collector == null) || (_collector.GridModel == null))
                return false;

            if (_collector.GridModel.Count < 1)
                return false;

            return true;
        }

        /// <summary>
        /// Starts the SlideShow at the given index in the CrystalCollector.
        /// </summary>
        /// <param name="startIndex">Starting index within the Collector object.</param>
        /// <returns>True if the slideshow started, false otherwise.</returns>
        public bool StartSlideShow(int startIndex)
        {
            if (!CanStartSlideShow())
                return false;

            _viewerMain.StartSlideShow(_collector, startIndex);
            _viewerMain.Focus();

            CurrentViewMode = CrystalViewMode.SlideShowMode;

            return true;
        }

        /// <summary>
        /// Allows the controller to know that the application is switching to full screen mode.
        /// NOTE: Form must take care of hiding caption, menus, toolbars, etc., before calling this method.
        /// </summary>
        public virtual void FullScreenMode()
        {
            _currentViewMode = CrystalViewMode.FullScreenView;
            SetFitImage();
        }

        /// <summary>
        /// Determines if the controller has been initialized.
        /// </summary>
        /// <returns>True if initialized, false otherwise.</returns>
        public bool IsControllerInitialized()
        {
            return (_viewerMain != null) && (_imageGridView != null);
        }

        /// <summary>
        /// Determines if the Collector is empty.
        /// </summary>
        /// <returns>True if the collector is empty, false otherwise.</returns>
        public bool IsCollectorEmpty()
        {
            if ((Collector == null) || (Collector.GridModel == null))
                return true;

            return (Collector.GridModel.Count < 1);
        }

        /// <summary>
        /// Selects an image in both the image grid view and the picture show object.
        /// </summary>
        /// <param name="imageItem">CrystalImageItem object.</param>
        public void SelectImage(CrystalImageItem imageItem)
        {
            if (imageItem != null)
            {
                _imageGridView.SelectImage(imageItem);
            }
        }

        /// <summary>
        /// Sets a null image in the picture show control and the image grid.
        /// </summary>
        public void SetNullImage()
        {
            _imageForm.Invoke(new MethodInvoker(delegate
                {
                    _viewerMain.Image = null;
                    _currentImage = null;
                }));
            // ???
            //_imageGridView.SelectImage(null);
        }

        #endregion

        #region Navigation

        /// <summary>
        /// Enables or disables the toolbar left button.
        /// </summary>
        /// <param name="stateValue">Boolean value indicating whether to enable or disable the button.</param>
        private void EnableBackButton(bool stateValue)
        {
            if (_leftButton != null)
                _leftButton.Enabled = stateValue;
        }

        /// <summary>
        /// Enables or disables the toolbar right button.
        /// </summary>
        /// <param name="stateValue">Boolean value indicating whether to enable or disable the button.</param>
        private void EnableForwardButton(bool stateValue)
        {
            if (_rightButton != null)
                _rightButton.Enabled = stateValue;
        }

        /// <summary>
        /// Enables the navigation left/right buttons on the Form's toolbar.
        /// </summary>
        private void EnableNavButtons()
        {
            if (!IsControllerInitialized())
                return;

            int totalThumbs = Collector.GridModel.Count;
            if (totalThumbs == 0)
            {
                EnableBackButton(false);
                EnableForwardButton(false);
            }
            else
            {
                int currentIndex = GetSelectedItemIndex();
                if (currentIndex > -1)
                {
                    EnableBackButton(currentIndex != 0);
                    EnableForwardButton(currentIndex != (totalThumbs - 1));
                }
            }
        }

        /// <summary>
        /// Displays the first image from the image model in the Collector.
        /// </summary>
        public void MoveToFirstImage()
        {
            _imageGridView.MoveToFirstImage(true, true);

            _currentImage = _imageGridView.FocusedImage;
        }

        /// <summary>
        /// Displays the very last image from the image model in the Collector.
        /// </summary>
        public void MoveToLastImage()
        {
            _imageGridView.MoveToLastImage(true, true);

            _currentImage = _imageGridView.FocusedImage;
        }

        /// <summary>
        /// Displays the previous image from the image model in the Collector.
        /// </summary>
        public void MoveToLeftImage()
        {
            if (_currentImage == null)
                return;

            _imageGridView.MoveToLeftImage(true, true);

            _currentImage = _imageGridView.FocusedImage;
        }

        /// <summary>
        /// Displays the next image from the image model in the Collector.
        /// </summary>
        public void MoveToRightImage()
        {
            if (_currentImage == null)
                return;

            _imageGridView.MoveToRightImage(true, true);

            _currentImage = _imageGridView.FocusedImage;
        }

        /// <summary>
        /// Refreshs the image model in the Collector and displays them in the ImageGridView.
        /// </summary>
        public void Refresh()
        {
            if (Collector != null)
            {
                int currentIndex = 0;
                string currentImageName = string.Empty;

                if (CurrentImage != null)
                {
					// cache the index and the name of the current image
                    currentIndex = GetSelectedItemIndex();
                    currentImageName = CurrentImage.ImageName;
                }

                Collector.CollectImages();

                // Try selecting the name first.
                // If that does not work--it has been deleted/renamed,
                // select the image index instead.
                if (!Collector.SelectImage(currentImageName))
                    Collector.SelectImage(currentIndex);
            }
        }

        #endregion

        #region Scale, TrackBar, Zoom Combo

        /// <summary>
        /// Sets the zoom factor in the CrystalPictureShow object and makes the image display Scrollable.
        /// </summary>
        /// <param name="newZoom">Zoom factor for image viewer.</param>
        public void SetZoomImage(float newZoom)
        {
            if (!IsControllerInitialized())
                return;

            _viewerMain.ImageSizeMode = SizeMode.Scrollable;
            _viewerMain.ZoomFactor = newZoom;
        }

        /// <summary>
        /// Sets the zoom factor in the CrystalImageGridView object.
        /// </summary>
        /// <param name="newZoom">Zoom factor for image thumbnail grid.</param>
        public void SetThumbZoomImage(float newZoom)
        {
            if (!IsControllerInitialized())
                return;

            _imageGridView.ZoomFactor = newZoom;
        }

        /// <summary>
        /// Sets the CrystalPictureShow object to display the current image in a mode that fits the display area.
        /// </summary>
        public void SetFitImage()
        {
            if (!IsControllerInitialized())
                return;

            _viewerMain.ZoomFactor = 1;
            _viewerMain.ImageSizeMode = SizeMode.RatioStretch;
        }

        /// <summary>
        /// Determines if the CrystalPictureShow object is display the image in RatioStretch mode.
        /// </summary>
        /// <returns></returns>
        public bool IsFitImage()
        {
            return _viewerMain.ImageSizeMode == SizeMode.RatioStretch;
        }

        /// <summary>
        /// Sets the value for ComboBox in the Form's toolstrip.
        /// </summary>
        /// <param name="value">String value to select in the combo box.</param>
        private void SetZoomComboText(string value)
        {
            _zoomComboBox.SelectedIndexChanged -= zoomComboBox_SelectedIndexChanged;
            _zoomComboBox.Text = value;
            _zoomComboBox.SelectedIndexChanged += zoomComboBox_SelectedIndexChanged;
        }

        /// <summary>
        /// Initializes the zoom combo box with an initial set of values.
        /// </summary>
        private void InitScaleCombo()
        {
            _zoomComboBox.Items.Clear();

            foreach (string scaleItem in _zoomFactorStringItems)
            {
                _zoomComboBox.Items.Add(scaleItem);
            }

            SetZoomComboText(_zoomFactorStringItems[_zoomFactorStringItems.Length - 1]);
            _zoomComboBox.Enabled = false;
        }

        /// <summary>
        /// Initializes the CrystalToolStripTrackBar on the Form's toolbar.
        /// </summary>
        protected void InitTrackBar()
        {
            SetTrackBarValue(5);
            _zoomToolStripTrackBar.Enabled = false;
            _zoomToolStripTrackBar.CrystalTrackBar.TransparentMode = false;
            _zoomToolStripTrackBar.CrystalTrackBar.Color1 = Color.LightBlue;
            _zoomToolStripTrackBar.CrystalTrackBar.Color2 = Color.DarkBlue;
        }

        protected void InitThumbTrackBar()
        {
            _thumbZoomToolStripTrackBar.Enabled = true;
            _thumbZoomToolStripTrackBar.CrystalTrackBar.TransparentMode = false;
            _thumbZoomToolStripTrackBar.CrystalTrackBar.Color1 = Color.LightBlue;
            _thumbZoomToolStripTrackBar.CrystalTrackBar.Color2 = Color.DarkBlue;
            _thumbZoomToolStripTrackBar.CrystalTrackBar.Minimum = 0;
            _thumbZoomToolStripTrackBar.CrystalTrackBar.Maximum = 5;

            SetThumbTrackBarValue(_defaultThumbZoom);
        }

        /// <summary>
        /// Handles the CrystalToolStripTrackBar ValueChanged event by adjusting the zoom factor for image view.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">Event arguments.</param>
        private void scrollZoom_Scroll(object sender, EventArgs e)
        {
            // The scrollZoom changed so reset the zoom factor
            // based on the scrollZoom TrackBar position.
            float newZoom = _zoomFactorFloatItems[_zoomToolStripTrackBar.Value];
            SetZoomComboText(_zoomFactorStringItems[_zoomToolStripTrackBar.Value]);

            SetZoomImage(newZoom);
        }

 
        /// <summary>
        /// Handles the CrystalToolStripTrackBar ValueChanged event by adjusting the zoom factor for thumbnail image grid.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">Event arguments.</param>
        private void scrollThumbZoom_Scroll(object sender, EventArgs e)
        {
            // The scrollZoom changed so reset the zoom factor
            // based on the scrollZoom TrackBar position.
            float newZoom = _thumbZoomFactorFloatItems[_thumbZoomToolStripTrackBar.Value];
            SetThumbZoomImage(newZoom);

            // save for later
            _cachedThumbZoom = _thumbZoomToolStripTrackBar.Value;
        }
       

        /// <summary>
        /// Handles the ZoomComboBox Selected Index changed event.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">Event arguments.</param>
        private void zoomComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            string zoomValue = _zoomComboBox.SelectedItem.ToString();

            if (zoomValue.Length < 1)
                return;

            if (zoomValue == _zoomFactorStringItems[_zoomFactorStringItems.Length - 1])
            {
                SetFitImage();
                SetScale();
            }
            else
            {
                float newZoom = _zoomFactorFloatItems[_zoomComboBox.SelectedIndex];
                SetZoomImage(newZoom);
                SetTrackBarValue(_zoomComboBox.SelectedIndex);
            }
        }

        /// <summary>
        /// Sets the value in the CrystalToolStripTrackBar object for image zoom.
        /// </summary>
        /// <param name="value">TrackBar position value.</param>
        private void SetTrackBarValue(int value)
        {
            if (!IsControllerInitialized())
                return;

            _zoomToolStripTrackBar.ValueChanged -= scrollZoom_Scroll;
            _zoomToolStripTrackBar.Value = value;
            _zoomToolStripTrackBar.ValueChanged += scrollZoom_Scroll;
        }

        /// <summary>
        /// Sets the value in the CrystalToolStripTrackBar object for thumbnail zoom.
        /// </summary>
        /// <param name="value">TrackBar position value.</param>
        private void SetThumbTrackBarValue(int value)
        {
            if (!IsControllerInitialized())
                return;

            _thumbZoomToolStripTrackBar.ValueChanged -= scrollThumbZoom_Scroll;
            _thumbZoomToolStripTrackBar.Value = value;
            _thumbZoomToolStripTrackBar.ValueChanged += scrollThumbZoom_Scroll;

            SetThumbZoomImage(_thumbZoomFactorFloatItems[value]);
        }

        /// <summary>
        /// Sets the appropriate scale in both the CrystalToolStripTrackBar and ComboBox objects
        /// based on the current zoom factor in the CrystalPictureShow object.
        /// </summary>
        public void SetScale()
        {
            if (!IsControllerInitialized())
                return;

            double scale = _viewerMain.ZoomFactor;

            int index = 0;
            foreach (double dValue in _zoomFactorFloatItems)
            {
                index++;
                if (scale <= dValue)
                {
                    scale = dValue;
                    break;
                }
            }

            if (index < _zoomToolStripTrackBar.CrystalTrackBar.Minimum)
                SetTrackBarValue(_zoomToolStripTrackBar.CrystalTrackBar.Minimum);
            else if (index > _zoomToolStripTrackBar.CrystalTrackBar.Maximum)
                SetTrackBarValue(_zoomToolStripTrackBar.CrystalTrackBar.Maximum);
            else
                SetTrackBarValue(index);

            if (!IsFitImage())
            {
                int wholeScale = Convert.ToInt32(scale*100);
                string comboScale = wholeScale.ToString();
                comboScale += "%";
                SetZoomComboText(comboScale);
            }
        }

        #endregion

        #region Tracker_Control

        protected virtual void ShowTrackerForViewMode()
        {
            if ((_currentViewMode == CrystalViewMode.SplitView) || (_currentViewMode == CrystalViewMode.ImageView))
            {
                ShowTracker(true);
            }
            else
            {
                ShowTracker(false);
            }
        }

        public virtual void InitTrackerControl()
        {
            if (_viewerMain != null)
            {
                _viewerMain.SetupTrackerWindow();
            }
        }

        public virtual void ShowTrackerOnZoom(bool bShow)
        {
            if (_viewerMain != null)
            {
                _viewerMain.ShowPanOnZoom = bShow;
                ShowTrackerForViewMode();
            }
        }

        private void ShowTracker(bool bShow)
        {
            if (_viewerMain != null)
            {
                _viewerMain.ShowTrackerWindow(bShow);
            }
        }

        #endregion

        protected void ShowThumbZoomForViewMode()
        {
            if (_thumbToolStrip == null)
                return;

            if (_currentViewMode == CrystalViewMode.ThumbView)
            {
                SetThumbTrackBarValue(_cachedThumbZoom);
                _thumbToolStrip.Visible = true;
            }
            else
            {
                _thumbToolStrip.Visible = false;
                SetThumbTrackBarValue(_defaultThumbSplitZoom);
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Software Developer (Senior)
United States United States
Richard has been working with Windows software since 1991. He has worked for Borland, Microsoft, Oracle, and various startup companies such as Livescribe. Currently he is developing projects in C#, Windows Forms, and Net Framework. Visit his blog Attilan (www.attilan.com) to learn more about his tools, projects and discoveries.

Comments and Discussions