PageRenderTime 42ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/odyssey-24878/Ribbon/Controls/RibbonQAToolBar.cs

#
C# | 364 lines | 235 code | 72 blank | 57 comment | 33 complexity | 2ae4d999e0a7145c17a1fa747bc0da2c MD5 | raw file
Possible License(s): AGPL-1.0, GPL-3.0, LGPL-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows.Controls;
  6. using System.Windows;
  7. using Odyssey.Controls.Ribbon.Interfaces;
  8. using System.Diagnostics;
  9. using System.Windows.Media;
  10. using System.Windows.Input;
  11. using System.Windows.Threading;
  12. using System.Windows.Data;
  13. #region Copyright
  14. // Odyssey.Controls.Ribbonbar
  15. // (c) copyright 2009 Thomas Gerber
  16. // This source code and files, is licensed under The Microsoft Public License (Ms-PL)
  17. #endregion
  18. namespace Odyssey.Controls
  19. {
  20. /// <summary>
  21. /// RibbonQuickAccessToolbar
  22. /// </summary>
  23. [TemplatePart(Name = partItemsHost)]
  24. [TemplatePart(Name = partOverflowHost)]
  25. [TemplatePart(Name = partMenuItemsHost)]
  26. public class RibbonQAToolBar : ItemsControl
  27. {
  28. const string partItemsHost = "PART_ToolBarPanel";
  29. const string partOverflowHost = "PART_OverflowHost";
  30. const string partMenuItemsHost = "PART_MenuItemHost";
  31. const string partMenuItemsOverflowHost = "PART_MenuItemOverflowHost";
  32. static RibbonQAToolBar()
  33. {
  34. DefaultStyleKeyProperty.OverrideMetadata(typeof(RibbonQAToolBar), new FrameworkPropertyMetadata(typeof(RibbonQAToolBar)));
  35. }
  36. public RibbonQAToolBar()
  37. : base()
  38. {
  39. AddHandler(RibbonButton.ClickEvent, new RoutedEventHandler(OnClick));
  40. AddHandler(RibbonSplitButton.ClickEvent, new RoutedEventHandler(OnClick));
  41. AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(OnMenuItemClick));
  42. }
  43. void OnClick(object sender, RoutedEventArgs e)
  44. {
  45. if (e.Source != this)
  46. {
  47. IsOverflowOpen = false;
  48. IsMenuOpen = false;
  49. }
  50. }
  51. void OnMenuItemClick(object sender, RoutedEventArgs e)
  52. {
  53. IsMenuOpen = false;
  54. IsOverflowOpen = false;
  55. }
  56. private Panel itemsHost;
  57. private Panel overflowHost;
  58. private Panel menuItemsHost;
  59. private Panel menuItemsOverflowHost;
  60. public override void OnApplyTemplate()
  61. {
  62. if (menuItemsOverflowHost != null) menuItemsOverflowHost.Children.Clear();
  63. if (menuItemsHost != null) menuItemsHost.Children.Clear();
  64. if (itemsHost != null) itemsHost.Children.Clear();
  65. if (overflowHost != null) overflowHost.Children.Clear();
  66. base.OnApplyTemplate();
  67. itemsHost = GetTemplateChild(partItemsHost) as Panel;
  68. overflowHost = GetTemplateChild(partOverflowHost) as Panel;
  69. menuItemsHost = GetTemplateChild(partMenuItemsHost) as Panel;
  70. menuItemsOverflowHost = GetTemplateChild(partMenuItemsOverflowHost) as Panel;
  71. if (itemsHost == null) throw new ArgumentException(partItemsHost + " is not defined in ControlTemplate.");
  72. }
  73. private IEnumerable<UIElement> GetMenuItems()
  74. {
  75. foreach (UIElement e in Items)
  76. {
  77. if (!(e is IRibbonButton)) yield return e;
  78. }
  79. }
  80. private IEnumerable<UIElement> GetToolbarItems()
  81. {
  82. foreach (UIElement e in Items)
  83. {
  84. if ((e is IRibbonButton)) yield return e;
  85. }
  86. }
  87. private void CreateMenuItems()
  88. {
  89. if (menuItemsHost != null)
  90. {
  91. HasMenuItems = false;
  92. if (menuItemsOverflowHost != null) menuItemsOverflowHost.Children.Clear();
  93. menuItemsHost.Children.Clear();
  94. Panel host = HasOverflowItems && menuItemsOverflowHost != null ? menuItemsOverflowHost : menuItemsHost;
  95. foreach (UIElement e in GetMenuItems())
  96. {
  97. host.Children.Add(e);
  98. //RibbonMenuItem mi = new RibbonMenuItem();
  99. //RibbonMenuItem rm = e as RibbonMenuItem;
  100. //if (rm != null)
  101. //{
  102. // Binding b = new Binding("IsChecked");
  103. // b.Source = e;
  104. // b.Mode = BindingMode.TwoWay;
  105. // mi.SetBinding(RibbonMenuItem.IsCheckedProperty, b);
  106. // mi.Image = (e as RibbonMenuItem).Image;
  107. // mi.Header = (e as RibbonMenuItem).Header;
  108. // mi.IsCheckable = rm.IsCheckable;
  109. //}
  110. //host.Children.Add(mi);
  111. HasMenuItems = true;
  112. }
  113. }
  114. }
  115. protected override System.Windows.Size MeasureOverride(System.Windows.Size constraint)
  116. {
  117. itemsHost.Children.Clear();
  118. if (overflowHost != null) overflowHost.Children.Clear();
  119. CreateMenuItems();
  120. foreach (UIElement e in GetToolbarItems())
  121. {
  122. RibbonBar.SetSize(e, RibbonSize.Small);
  123. itemsHost.Children.Add(e);
  124. }
  125. HasOverflowItems = false;
  126. Size maxSize = base.MeasureOverride(new Size(double.PositiveInfinity, constraint.Height));
  127. while (maxSize.Width > constraint.Width)
  128. {
  129. int n = itemsHost.Children.Count;
  130. if (n == 0) break;
  131. UIElement e = itemsHost.Children[n - 1];
  132. InvalidateAncestorMeasure(e);
  133. itemsHost.Children.RemoveAt(n - 1);
  134. if (overflowHost != null)
  135. {
  136. overflowHost.Children.Insert(0, e);
  137. HasOverflowItems = true;
  138. }
  139. maxSize = base.MeasureOverride(new Size(double.PositiveInfinity, constraint.Height));
  140. }
  141. Size size = base.MeasureOverride(constraint);
  142. return size;
  143. }
  144. private void InvalidateAncestorMeasure(DependencyObject obj)
  145. {
  146. UIElement element = obj as UIElement;
  147. if (element != null)
  148. {
  149. element.InvalidateMeasure();
  150. }
  151. if ((obj != this) && (obj != null))
  152. {
  153. this.InvalidateAncestorMeasure(VisualTreeHelper.GetParent(obj));
  154. }
  155. }
  156. /// <summary>
  157. /// Specifies where the QuickAccessToolBar is supposed to be placed.
  158. /// Depending on this information, the layout and design may vary.
  159. /// This is a dependency property.
  160. /// </summary>
  161. public QAPlacement ToolBarPlacement
  162. {
  163. get { return (QAPlacement)GetValue(ToolBarPlacementProperty); }
  164. set { SetValue(ToolBarPlacementProperty, value); }
  165. }
  166. // Using a DependencyProperty as the backing store for Placement. This enables animation, styling, binding, etc...
  167. public static readonly DependencyProperty ToolBarPlacementProperty =
  168. DependencyProperty.Register("ToolBarPlacement", typeof(QAPlacement), typeof(RibbonQAToolBar),
  169. new FrameworkPropertyMetadata(QAPlacement.Top,
  170. FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsRender));
  171. /// <summary>
  172. /// Gets or sets whether the overflow panel button is visible.
  173. /// This is a dependency property.
  174. /// </summary>
  175. public bool HasOverflowItems
  176. {
  177. get { return (bool)GetValue(IsOverflowVisibleProperty); }
  178. set { SetValue(IsOverflowVisibleProperty, value); }
  179. }
  180. // Using a DependencyProperty as the backing store for IsDropDownVisible. This enables animation, styling, binding, etc...
  181. public static readonly DependencyProperty IsOverflowVisibleProperty =
  182. DependencyProperty.Register("HasOverflowItems", typeof(bool), typeof(RibbonQAToolBar),
  183. new UIPropertyMetadata(false, HasOverflowItemsPropertyChanged));
  184. private static void HasOverflowItemsPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
  185. {
  186. RibbonQAToolBar toolbar = (RibbonQAToolBar)o;
  187. toolbar.CreateMenuItems();
  188. }
  189. /// <summary>
  190. /// Gets or sets whether the overflow panel is open.
  191. /// This is a dependency property.
  192. /// </summary>
  193. public bool IsOverflowOpen
  194. {
  195. get { return (bool)GetValue(IsOverflowOpenProperty); }
  196. set { SetValue(IsOverflowOpenProperty, value); }
  197. }
  198. // Using a DependencyProperty as the backing store for IsDropDownVisible. This enables animation, styling, binding, etc...
  199. public static readonly DependencyProperty IsOverflowOpenProperty =
  200. DependencyProperty.Register("IsOverflowOpen", typeof(bool), typeof(RibbonQAToolBar), new FrameworkPropertyMetadata(false,
  201. FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OverflowOpenPropertyChanged));
  202. public static void OverflowOpenPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
  203. {
  204. RibbonQAToolBar tb = (RibbonQAToolBar)o;
  205. tb.IsMenuOpen=false;
  206. }
  207. /// <summary>
  208. /// Gets or sets whether the menu is open.
  209. /// This is a dependency property.
  210. /// </summary>
  211. public bool IsMenuOpen
  212. {
  213. get { return (bool)GetValue(IsMenuOpenProperty); }
  214. set { SetValue(IsMenuOpenProperty, value); }
  215. }
  216. // Using a DependencyProperty as the backing store for IsMenuOpen. This enables animation, styling, binding, etc...
  217. public static readonly DependencyProperty IsMenuOpenProperty =
  218. DependencyProperty.Register("IsMenuOpen", typeof(bool), typeof(RibbonQAToolBar),
  219. new FrameworkPropertyMetadata(false,
  220. FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
  221. /// <summary>
  222. /// Gets or sets whether the menu button is visible.
  223. /// This is a dependency property.
  224. /// </summary>
  225. public bool HasMenuItems
  226. {
  227. get { return (bool)GetValue(HasMenuItemsProperty); }
  228. set { SetValue(HasMenuItemsProperty, value); }
  229. }
  230. // Using a DependencyProperty as the backing store for HasMenuItems. This enables animation, styling, binding, etc...
  231. public static readonly DependencyProperty HasMenuItemsProperty =
  232. DependencyProperty.Register("HasMenuItems", typeof(bool), typeof(RibbonQAToolBar), new UIPropertyMetadata(false));
  233. /// <summary>
  234. /// Gets or sets the header that appears in the menu.
  235. /// </summary>
  236. public object MenuHeader
  237. {
  238. get { return (object)GetValue(MenuHeaderProperty); }
  239. set { SetValue(MenuHeaderProperty, value); }
  240. }
  241. // Using a DependencyProperty as the backing store for MenuHeader. This enables animation, styling, binding, etc...
  242. public static readonly DependencyProperty MenuHeaderProperty =
  243. DependencyProperty.Register("MenuHeader", typeof(object), typeof(RibbonQAToolBar), new UIPropertyMetadata(null));
  244. public DataTemplate MenuHeaderTemplate
  245. {
  246. get { return (DataTemplate)GetValue(MenuHeaderTemplateProperty); }
  247. set { SetValue(MenuHeaderTemplateProperty, value); }
  248. }
  249. // Using a DependencyProperty as the backing store for MenuHeaderTemplate. This enables animation, styling, binding, etc...
  250. public static readonly DependencyProperty MenuHeaderTemplateProperty =
  251. DependencyProperty.Register("MenuHeaderTemplate", typeof(DataTemplate), typeof(RibbonQAToolBar), new UIPropertyMetadata(null));
  252. /// <summary>
  253. /// Gets or sets the footer that appears in the menu panel.
  254. /// </summary>
  255. public object MenuFooter
  256. {
  257. get { return (object)GetValue(MenuFooterProperty); }
  258. set { SetValue(MenuFooterProperty, value); }
  259. }
  260. // Using a DependencyProperty as the backing store for PopupFooter. This enables animation, styling, binding, etc...
  261. public static readonly DependencyProperty MenuFooterProperty =
  262. DependencyProperty.Register("MenuFooter", typeof(object), typeof(RibbonQAToolBar), new UIPropertyMetadata(null));
  263. public DataTemplate MenuFooterTemplate
  264. {
  265. get { return (DataTemplate)GetValue(MenuFooterTemplateProperty); }
  266. set { SetValue(MenuFooterTemplateProperty, value); }
  267. }
  268. // Using a DependencyProperty as the backing store for MenuFooterTemplate. This enables animation, styling, binding, etc...
  269. public static readonly DependencyProperty MenuFooterTemplateProperty =
  270. DependencyProperty.Register("MenuFooterTemplate", typeof(DataTemplate), typeof(RibbonQAToolBar), new UIPropertyMetadata(null));
  271. [AttachedPropertyBrowsableForChildren]
  272. public static QAItemPlacement GetPlacement(DependencyObject obj)
  273. {
  274. return (QAItemPlacement)obj.GetValue(PlacementProperty);
  275. }
  276. public static void SetPlacement(DependencyObject obj, QAItemPlacement value)
  277. {
  278. obj.SetValue(PlacementProperty, value);
  279. }
  280. // Using a DependencyProperty as the backing store for Placement. This enables animation, styling, binding, etc...
  281. public static readonly DependencyProperty PlacementProperty =
  282. DependencyProperty.RegisterAttached("Placement", typeof(QAItemPlacement), typeof(RibbonQAToolBar), new UIPropertyMetadata(QAItemPlacement.ToolBar));
  283. public DataTemplate ItemsTemplate
  284. {
  285. get { return (DataTemplate)GetValue(ItemsTemplateProperty); }
  286. set { SetValue(ItemsTemplateProperty, value); }
  287. }
  288. // Using a DependencyProperty as the backing store for ItemsTemplate. This enables animation, styling, binding, etc...
  289. public static readonly DependencyProperty ItemsTemplateProperty =
  290. DependencyProperty.Register("ItemsTemplate", typeof(DataTemplate), typeof(RibbonQAToolBar), new UIPropertyMetadata(null));
  291. }
  292. }