/Application/GUI/Controls/Details.xaml.cs
http://yet-another-music-application.googlecode.com/ · C# · 492 lines · 300 code · 71 blank · 121 comment · 39 complexity · 06907485180f5c5b25de761e3dc6becd MD5 · raw file
- /**
- * Details.xaml.cs
- *
- * The details pane which shows an image, a title, a description
- * and a number of key-value fields.
- * It automatically hides fields that cannot be shown and supports
- * for in-place edit of certain fields.
- *
- * * * * * * * * *
- *
- * This code is part of the Stoffi Music Player Project.
- * Visit our website at: stoffiplayer.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 3 of the License, or (at your option) any later version.
- *
- * See stoffiplayer.com/license for more information.
- **/
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Documents;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- using System.Windows.Navigation;
- using System.Windows.Shapes;
- using System.Windows.Controls.Primitives;
-
- namespace Stoffi
- {
- /// <summary>
- /// Details.xaml 的交互逻辑
- /// </summary>
- public partial class Details : StatusBar
- {
- #region Members
- private List<TextBlock> labels = new List<TextBlock>();
- private List<FrameworkElement> fields = new List<FrameworkElement>();
- private double cellWidth = 120;
- private double labelWidth = 80;
- private double cellHeight = 20;
- #endregion
-
- #region Properties
-
- /// <summary>
- /// The title of the item
- /// </summary>
- public string Title
- {
- get { return TitleBlock.Text; }
- set { TitleBlock.Text = value; }
- }
-
- /// <summary>
- /// A short description of the item
- /// </summary>
- public string Description
- {
- get { return DescrBlock.Text; }
- set { DescrBlock.Text = value; }
- }
-
- /// <summary>
- /// Sets the thumbnail image
- /// </summary>
- public ImageSource Image
- {
- get { return AlbumArt.Source; }
- set { AlbumArt.Source = value; }
- }
-
- #endregion
-
- #region Constructor
- /// <summary>
- /// Details Pane
- /// </summary>
- public Details()
- {
- U.L(LogLevel.Debug, "DETAILS", "Initialize");
- InitializeComponent();
- U.L(LogLevel.Debug, "DETAILS", "Initialized");
- FieldsGrid.RowDefinitions[0].Height = new GridLength(cellHeight);
- FieldsGrid.RowDefinitions[1].Height = new GridLength(cellHeight);
- FieldsGrid.ColumnDefinitions[0].Width = new GridLength(labelWidth);
- FieldsGrid.ColumnDefinitions[1].Width = new GridLength(cellWidth);
-
- if (System.Windows.Forms.VisualStyles.VisualStyleInformation.DisplayName == "")
- DescrBlock.Foreground = Brushes.Black;
- U.L(LogLevel.Debug, "DETAILS", "Created");
- }
- #endregion
-
- #region Methods
-
- #region Public
-
- /// <summary>
- /// Adds a text field
- /// </summary>
- /// <param name="name">The name of the field</param>
- /// <param name="value">The value of the field</param>
- /// <param name="editable">Whether the field can be edited</param>
- public void AddField(string name, string value, bool editable = false)
- {
- EditableTextBlock etb = new EditableTextBlock();
- etb.IsEditable = editable;
- etb.ClickToEdit = editable;
- etb.Text = value;
- etb.VerticalAlignment = System.Windows.VerticalAlignment.Center;
- etb.Edited += new EditableTextBlockDelegate(Field_Edited);
- etb.EnteredEditMode += new EventHandler(Field_EnteredEditMode);
- AddField(name, etb);
- }
-
- /// <summary>
- /// Adds a rating field
- /// </summary>
- /// <param name="name">The name of the field</param>
- /// <param name="i">The rate value (0-10)</param>
- public void AddField(string name, int i)
- {
- // TODO: create rate control
- }
-
- /// <summary>
- /// Adds a field
- /// </summary>
- /// <param name="name">The name of the field</param>
- /// <param name="e">The object representing the value</param>
- public void AddField(string name, FrameworkElement e)
- {
- e.Tag = name;
-
- int col = (int)Math.Floor((double)fields.Count + 2) / FieldsGrid.RowDefinitions.Count;
- int row = fields.Count + 2 - col * FieldsGrid.RowDefinitions.Count;
- col *= 2;
-
- TextBlock label = new TextBlock();
- label.Text = name + ':';
- label.TextAlignment = TextAlignment.Right;
- label.VerticalAlignment = System.Windows.VerticalAlignment.Center;
- label.Margin = new Thickness(0, 0, 2, 0);
- label.Padding = new Thickness(0);
- if (System.Windows.Forms.VisualStyles.VisualStyleInformation.DisplayName != "")
- label.Foreground = new SolidColorBrush(Color.FromRgb(90, 103, 121));
- label.Tag = name;
- Grid.SetRow(label, row);
- Grid.SetColumn(label, col);
-
- e.Margin = new Thickness(2);
- e.Tag = name;
- Grid.SetRow(e, row);
- Grid.SetColumn(e, col + 1);
-
- if (col >= FieldsGrid.ColumnDefinitions.Count || row >= FieldsGrid.RowDefinitions.Count)
- {
- label.Visibility = System.Windows.Visibility.Collapsed;
- e.Visibility = System.Windows.Visibility.Collapsed;
- }
-
- FieldsGrid.Children.Add(label);
- labels.Add(label);
- FieldsGrid.Children.Add(e);
- fields.Add(e);
- RefreshGrid();
- }
-
- /// <summary>
- /// Removes a field
- /// </summary>
- /// <param name="name">The name of the field to remove</param>
- public void RemoveField(string name)
- {
- for (int i = 0; i < fields.Count; i++)
- {
- FrameworkElement e = fields[i];
- if ((string)e.Tag == name)
- {
- FieldsGrid.Children.Remove(e);
- fields.RemoveAt(i);
- i--;
- }
- }
- for (int i = 0; i < labels.Count; i++)
- {
- FrameworkElement e = fields[i];
- if ((string)e.Tag == name)
- {
- FieldsGrid.Children.Remove(e);
- labels.RemoveAt(i);
- i--;
- }
- }
- RefreshGrid();
- }
-
- /// <summary>
- /// Changes the value of a field
- /// </summary>
- /// <param name="name">The name of the field</param>
- /// <param name="value">The new value of the field</param>
- public void SetField(string name, string value)
- {
- foreach (FrameworkElement e in fields)
- {
- if (e.Tag as string == name && e is EditableTextBlock)
- (e as EditableTextBlock).Text = value;
- else if (e.Tag as string == name && e is TextBlock)
- (e as TextBlock).Text = value;
- }
- }
-
- /// <summary>
- /// Removes all fields and resets control
- /// </summary>
- public void Clear()
- {
- AlbumArt.Visibility = System.Windows.Visibility.Hidden;
-
- fields.Clear();
- labels.Clear();
- FieldsGrid.Children.Clear();
-
- Title = "";
- Description = "";
-
- FieldsGrid.Children.Add(TitleBlock);
- FieldsGrid.Children.Add(DescrBlock);
-
- RefreshGrid();
- }
-
- #endregion
-
- #region Private
-
- /// <summary>
- /// Refreshes the content inside the grid
- /// </summary>
- private void RefreshFields()
- {
- int i = 0;
- for (int col = 0; i < fields.Count && col < FieldsGrid.ColumnDefinitions.Count; col += 2) // double increase
- {
- for (int row = col == 0 ? 2 : 0; i < fields.Count && row < FieldsGrid.RowDefinitions.Count; row++, i++)
- {
- fields[i].Visibility = System.Windows.Visibility.Visible;
- labels[i].Visibility = System.Windows.Visibility.Visible;
- Grid.SetColumn(labels[i], col);
- Grid.SetRow(labels[i], row);
- Grid.SetColumn(fields[i], col + 1);
- Grid.SetRow(fields[i], row);
- }
- }
- while (i < fields.Count)
- {
- fields[i].Visibility = System.Windows.Visibility.Collapsed;
- labels[i].Visibility = System.Windows.Visibility.Collapsed;
- i++;
- }
-
- AlbumArt.Visibility = fields.Count > 0 ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden;
- }
-
- /// <summary>
- /// Refreshes the grids column and row configuration
- /// </summary>
- private void RefreshGrid()
- {
- #region Add columns
-
- int allowed = (int)Math.Floor(RightPart.RenderSize.Width / (cellWidth + labelWidth));
- int actual = FieldsGrid.ColumnDefinitions.Count / 2;
-
- if (allowed > actual)
- {
- int add = allowed - actual;
-
- for (int i = 0; i < add; i++)
- {
- FieldsGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(labelWidth) });
- FieldsGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(cellWidth) });
- RefreshFields();
- }
- }
- #endregion
-
- #region Remove columns
- if (actual > allowed)
- {
- int remove = actual - allowed;
- FieldsGrid.ColumnDefinitions.RemoveRange(
- FieldsGrid.ColumnDefinitions.Count - (remove*2), remove*2);
- }
- #endregion
-
- allowed = (int)Math.Floor(RightPart.RenderSize.Height / cellHeight);
- actual = FieldsGrid.RowDefinitions.Count;
-
- #region Add rows
- if (allowed > actual)
- {
- for (int i = 0; i < allowed - actual; i++)
- {
- int index = actual + i;
- double add = allowed;
- FieldsGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(cellHeight) });
-
- for (int j = 0; j < FieldsGrid.ColumnDefinitions.Count; j += 2)
- {
- TextBlock tb1 = new TextBlock()
- {
- Text = "Foo:",
- Background = Brushes.Blue,
- Margin = new Thickness(2),
- Width = labelWidth
- };
-
- TextBlock tb2 = new TextBlock()
- {
- Text = "Bar",
- Background = Brushes.Red,
- Margin = new Thickness(2),
- Width = cellWidth
- };
-
- Grid.SetColumn(tb1, j);
- Grid.SetColumn(tb2, j + 1);
-
- Grid.SetRow(tb1, FieldsGrid.RowDefinitions.Count - 1);
- Grid.SetRow(tb2, FieldsGrid.RowDefinitions.Count - 1);
- }
- }
- }
- #endregion
-
- #region Remove rows
- else if (allowed < actual)
- {
- int remove = actual - allowed;
- FieldsGrid.RowDefinitions.RemoveRange(
- FieldsGrid.RowDefinitions.Count - remove, remove);
-
- if (FieldsGrid.RowDefinitions.Count == 0)
- FieldsGrid.Children.Clear();
- }
- #endregion
-
- RefreshFields();
- }
-
- #endregion
-
- #region Event handlers
-
- /// <summary>
- /// Invoked when the size changes.
- /// Will add or remove rows or columns
- /// and call Refresh().
- /// </summary>
- /// <param name="sender">The sender of the event</param>
- /// <param name="e">The event data</param>
- private void Details_SizeChanged(object sender, SizeChangedEventArgs e)
- {
- RefreshGrid();
- }
-
- /// <summary>
- /// Invoked when a field has been edited
- /// </summary>
- /// <param name="sender">The sender of the event</param>
- /// <param name="e">The event data</param>
- private void Field_Edited(object sender, EditableTextBlockEventArgs e)
- {
- EditableTextBlock etb = sender as EditableTextBlock;
- OnFieldEdited(etb.Tag as string, e.NewText);
- }
-
- /// <summary>
- /// Invoked when a field enters edit mode
- /// </summary>
- /// <param name="sender">The sender of the event</param>
- /// <param name="e">The event data</param>
- private void Field_EnteredEditMode(object sender, EventArgs e)
- {
- OnEnteredEditMode(sender);
- }
-
- #endregion
-
- #region Dispatchers
-
- /// <summary>
- /// Dispatches the FieldEdited event
- /// </summary>
- /// <param name="name">The name of the field</param>
- /// <param name="value">The new value of the field</param>
- private void OnFieldEdited(string name, string value)
- {
- if (FieldEdited != null)
- FieldEdited(this, new FieldEditedEventArgs(name, value));
- }
-
- /// <summary>
- /// Dispatches the EnteredEditMode event
- /// </summary>
- /// <param name="etb">The object that sent the event</param>
- private void OnEnteredEditMode(object etb)
- {
- if (EnteredEditMode != null)
- EnteredEditMode(etb, new EventArgs());
- }
-
- #endregion
-
- #endregion
-
- #region Events
-
- /// <summary>
- /// Occurs when a field was edited
- /// </summary>
- public event FieldEditedEventHandler FieldEdited;
-
-
- /// <summary>
- /// Occurs when the control enters edit mode
- /// </summary>
- public event EventHandler EnteredEditMode;
-
- #endregion
-
- #region Delegates
-
- /// <summary>
- /// Represents the method that will handle the FieldEdited event.
- /// </summary>
- /// <param name="sender">The sender of the event</param>
- /// <param name="e">The event data</param>
- public delegate void FieldEditedEventHandler(object sender, FieldEditedEventArgs e);
-
- #endregion
- }
-
- #region Event arguments
-
- /// <summary>
- /// Provides data for the <see cref="Details.FieldEdited"/> event
- /// </summary>
- public class FieldEditedEventArgs : EventArgs
- {
- #region Properties
-
- /// <summary>
- /// Gets the name of the field
- /// </summary>
- public string Field { get; private set; }
-
- /// <summary>
- /// Gets the new value of the field
- /// </summary>
- public string Value { get; private set; }
-
- #endregion
-
- #region Constructor
-
- /// <summary>
- /// Initializes a new instance of the <see cref="FieldEditedEventArgs"/> class
- /// </summary>
- /// <param name="field">The name of the field</param>
- /// <param name="value">The new value of the field</param>
- public FieldEditedEventArgs(string field, string value)
- {
- Field = field;
- Value = value;
- }
-
- #endregion
- }
-
- #endregion
- }