ToolBar.cs 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000
  1. //
  2. // System.Windows.Forms.ToolBar.cs
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining
  5. // a copy of this software and associated documentation files (the
  6. // "Software"), to deal in the Software without restriction, including
  7. // without limitation the rights to use, copy, modify, merge, publish,
  8. // distribute, sublicense, and/or sell copies of the Software, and to
  9. // permit persons to whom the Software is furnished to do so, subject to
  10. // the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be
  13. // included in all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  19. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  20. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  21. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. //
  23. // Author:
  24. // Ravindra ([email protected])
  25. //
  26. // TODO:
  27. // - Drawing ellipsis when text is too big to draw on a button
  28. // - RightToLeft
  29. // - DropDown ContextMenu
  30. // - Tooltip
  31. //
  32. // Copyright (C) Novell Inc., 2004 (http://www.novell.com)
  33. //
  34. //
  35. // $Revision: 1.12 $
  36. // $Modtime: $
  37. // $Log: ToolBar.cs,v $
  38. // Revision 1.12 2004/09/28 18:44:25 pbartok
  39. // - Streamlined Theme interfaces:
  40. // * Each DrawXXX method for a control now is passed the object for the
  41. // control to be drawn in order to allow accessing any state the theme
  42. // might require
  43. //
  44. // * ControlPaint methods for the theme now have a CP prefix to avoid
  45. // name clashes with the Draw methods for controls
  46. //
  47. // * Every control now retrieves it's DefaultSize from the current theme
  48. //
  49. // Revision 1.11 2004/09/16 13:00:19 ravindra
  50. // Invalidate should be done before redrawing.
  51. //
  52. // Revision 1.10 2004/09/09 11:25:03 ravindra
  53. // Make redraw accessible from ToolBarButton.
  54. //
  55. // Revision 1.9 2004/08/25 20:04:40 ravindra
  56. // Added the missing divider code and grip for ToolBar Control.
  57. //
  58. // Revision 1.8 2004/08/25 00:43:13 ravindra
  59. // Fixed wrapping related issues in ToolBar control.
  60. //
  61. // Revision 1.7 2004/08/22 01:20:14 ravindra
  62. // Correcting the formatting mess of VS.NET.
  63. //
  64. // Revision 1.6 2004/08/22 00:49:37 ravindra
  65. // Probably this completes the missing attributes in toolbar control.
  66. //
  67. // Revision 1.5 2004/08/22 00:03:20 ravindra
  68. // Fixed toolbar control signatures.
  69. //
  70. // Revision 1.4 2004/08/21 01:52:08 ravindra
  71. // Improvments in mouse event handling in the ToolBar control.
  72. //
  73. // Revision 1.3 2004/08/17 02:00:54 ravindra
  74. // Added attributes.
  75. //
  76. // Revision 1.2 2004/08/17 00:48:50 ravindra
  77. // Added attributes.
  78. //
  79. // Revision 1.1 2004/08/15 23:13:15 ravindra
  80. // First Implementation of ToolBar control.
  81. //
  82. //
  83. // NOT COMPLETE
  84. using System.Collections;
  85. using System.Drawing;
  86. using System.Drawing.Imaging;
  87. using System.ComponentModel;
  88. using System.ComponentModel.Design;
  89. using System.Runtime.InteropServices;
  90. namespace System.Windows.Forms
  91. {
  92. [DefaultEvent ("ButtonClick")]
  93. [DefaultProperty ("Buttons")]
  94. [Designer ("System.Windows.Forms.Design.ToolBarDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
  95. public class ToolBar : Control
  96. {
  97. #region Instance Variables
  98. internal ToolBarAppearance appearance;
  99. internal bool autosize;
  100. internal BorderStyle borderStyle;
  101. internal ToolBarButtonCollection buttons;
  102. internal Size buttonSize;
  103. internal bool divider;
  104. internal bool dropDownArrows;
  105. internal ImageList imageList;
  106. internal ImeMode imeMode;
  107. internal bool showToolTips;
  108. internal ToolBarTextAlign textAlignment;
  109. internal bool wrappable; // flag to make the toolbar wrappable
  110. internal bool redraw; // flag to force redrawing the control
  111. internal ToolBarButton currentButton; // the highlighted button
  112. #endregion Instance Variables
  113. #region Events
  114. [Browsable (false)]
  115. [EditorBrowsable (EditorBrowsableState.Never)]
  116. public new event EventHandler BackColorChanged;
  117. [Browsable (false)]
  118. [EditorBrowsable (EditorBrowsableState.Never)]
  119. public new event EventHandler BackgroundImageChanged;
  120. public event ToolBarButtonClickEventHandler ButtonClick;
  121. public event ToolBarButtonClickEventHandler ButtonDropDown;
  122. [Browsable (false)]
  123. [EditorBrowsable (EditorBrowsableState.Never)]
  124. public new event EventHandler ForeColorChanged;
  125. [Browsable (false)]
  126. [EditorBrowsable (EditorBrowsableState.Never)]
  127. public new event EventHandler ImeModeChanged;
  128. [Browsable (false)]
  129. [EditorBrowsable (EditorBrowsableState.Never)]
  130. public new event PaintEventHandler Paint;
  131. [Browsable (false)]
  132. [EditorBrowsable (EditorBrowsableState.Never)]
  133. public new event EventHandler RightToLeftChanged;
  134. [Browsable (false)]
  135. [EditorBrowsable (EditorBrowsableState.Never)]
  136. public new event EventHandler TextChanged;
  137. #endregion Events
  138. #region Constructor
  139. public ToolBar ()
  140. {
  141. appearance = ToolBarAppearance.Normal;
  142. autosize = true;
  143. background_color = ThemeEngine.Current.DefaultControlBackColor;
  144. borderStyle = BorderStyle.None;
  145. buttons = new ToolBarButtonCollection (this);
  146. buttonSize = Size.Empty;
  147. divider = true;
  148. dropDownArrows = false;
  149. foreground_color = ThemeEngine.Current.DefaultControlForeColor;
  150. showToolTips = false;
  151. textAlignment = ToolBarTextAlign.Underneath;
  152. wrappable = true;
  153. dock_style = DockStyle.Top;
  154. redraw = true;
  155. // event handlers
  156. this.MouseDown += new MouseEventHandler (ToolBar_MouseDown);
  157. this.MouseLeave += new EventHandler (ToolBar_MouseLeave);
  158. this.MouseMove += new MouseEventHandler (ToolBar_MouseMove);
  159. this.MouseUp += new MouseEventHandler (ToolBar_MouseUp);
  160. base.Paint += new PaintEventHandler (ToolBar_Paint);
  161. }
  162. #endregion Constructor
  163. #region protected Properties
  164. protected override CreateParams CreateParams
  165. {
  166. get { return base.CreateParams; }
  167. }
  168. protected override ImeMode DefaultImeMode {
  169. get { return ImeMode.Disable; }
  170. }
  171. protected override Size DefaultSize {
  172. get { return ThemeEngine.Current.ToolBarDefaultSize; }
  173. }
  174. #endregion
  175. #region Public Properties
  176. [DefaultValue (ToolBarAppearance.Normal)]
  177. [Localizable (true)]
  178. public ToolBarAppearance Appearance {
  179. get { return appearance; }
  180. set {
  181. if (value == appearance)
  182. return;
  183. appearance = value;
  184. Redraw (false);
  185. }
  186. }
  187. [DefaultValue (true)]
  188. [Localizable (true)]
  189. public bool AutoSize {
  190. get { return autosize; }
  191. set {
  192. if (value == autosize)
  193. return;
  194. autosize = value;
  195. Redraw (true);
  196. }
  197. }
  198. [Browsable (false)]
  199. [EditorBrowsable (EditorBrowsableState.Never)]
  200. public override Color BackColor {
  201. get { return background_color; }
  202. set {
  203. if (value == background_color)
  204. return;
  205. background_color = value;
  206. if (BackColorChanged != null)
  207. BackColorChanged (this, new EventArgs ());
  208. Redraw (false);
  209. }
  210. }
  211. [Browsable (false)]
  212. [EditorBrowsable (EditorBrowsableState.Never)]
  213. public override Image BackgroundImage {
  214. get { return background_image; }
  215. set {
  216. if (value == background_image)
  217. return;
  218. background_image = value;
  219. if (BackgroundImageChanged != null)
  220. BackgroundImageChanged (this, new EventArgs ());
  221. Redraw (false);
  222. }
  223. }
  224. [DefaultValue (BorderStyle.None)]
  225. [DispIdAttribute (-504)]
  226. public BorderStyle BorderStyle {
  227. get { return borderStyle; }
  228. set {
  229. if (value == borderStyle)
  230. return;
  231. borderStyle = value;
  232. Redraw (false);
  233. }
  234. }
  235. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  236. [Localizable (true)]
  237. [MergableProperty (false)]
  238. public ToolBarButtonCollection Buttons {
  239. get { return buttons; }
  240. }
  241. [Localizable (true)]
  242. [RefreshProperties (RefreshProperties.All)]
  243. public Size ButtonSize {
  244. get {
  245. if (buttonSize.IsEmpty) {
  246. if (buttons.Count == 0)
  247. return new Size (39, 36);
  248. else
  249. return CalcButtonSize ();
  250. }
  251. return buttonSize;
  252. }
  253. set {
  254. if (buttonSize.Width == value.Width && buttonSize.Height == value.Height)
  255. return;
  256. if (value.Width > 0 && value.Height > 0) {
  257. buttonSize = value;
  258. Redraw (true);
  259. }
  260. }
  261. }
  262. [DefaultValue (true)]
  263. public bool Divider {
  264. get { return divider; }
  265. set {
  266. if (value == divider)
  267. return;
  268. divider = value;
  269. Redraw (false);
  270. }
  271. }
  272. [DefaultValue (DockStyle.Top)]
  273. [Localizable (true)]
  274. public override DockStyle Dock {
  275. get { return base.Dock; }
  276. set { base.Dock = value; }
  277. }
  278. [DefaultValue (false)]
  279. [Localizable (true)]
  280. public bool DropDownArrows {
  281. get { return dropDownArrows; }
  282. set {
  283. if (value == dropDownArrows)
  284. return;
  285. dropDownArrows = value;
  286. Redraw (true);
  287. }
  288. }
  289. [Browsable (false)]
  290. [EditorBrowsable (EditorBrowsableState.Never)]
  291. public override Color ForeColor {
  292. get { return foreground_color; }
  293. set {
  294. if (value == foreground_color)
  295. return;
  296. foreground_color = value;
  297. if (ForeColorChanged != null)
  298. ForeColorChanged (this, new EventArgs ());
  299. Redraw (false);
  300. }
  301. }
  302. [DefaultValue (null)]
  303. public ImageList ImageList {
  304. get { return imageList; }
  305. set { imageList = value; }
  306. }
  307. [Browsable (false)]
  308. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  309. [EditorBrowsable (EditorBrowsableState.Advanced)]
  310. public Size ImageSize {
  311. get {
  312. if (imageList == null)
  313. return Size.Empty;
  314. return imageList.ImageSize;
  315. }
  316. }
  317. [Browsable (false)]
  318. [EditorBrowsable (EditorBrowsableState.Never)]
  319. public new ImeMode ImeMode {
  320. get { return imeMode; }
  321. set {
  322. if (value == imeMode)
  323. return;
  324. imeMode = value;
  325. if (ImeModeChanged != null)
  326. ImeModeChanged (this, new EventArgs ());
  327. }
  328. }
  329. [Browsable (false)]
  330. [EditorBrowsable (EditorBrowsableState.Never)]
  331. public override RightToLeft RightToLeft {
  332. get { return base.RightToLeft; }
  333. set {
  334. if (value == base.RightToLeft)
  335. return;
  336. base.RightToLeft = value;
  337. if (RightToLeftChanged != null)
  338. RightToLeftChanged (this, new EventArgs ());
  339. }
  340. }
  341. [DefaultValue (false)]
  342. [Localizable (true)]
  343. public bool ShowToolTips {
  344. get { return showToolTips; }
  345. set { showToolTips = value; }
  346. }
  347. [DefaultValue (false)]
  348. public new bool TabStop {
  349. get { return base.TabStop; }
  350. set { base.TabStop = value; }
  351. }
  352. [Bindable (false)]
  353. [Browsable (false)]
  354. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  355. [EditorBrowsable (EditorBrowsableState.Never)]
  356. public override string Text {
  357. get { return text; }
  358. set {
  359. if (value == text)
  360. return;
  361. text = value;
  362. Redraw (true);
  363. if (TextChanged != null)
  364. TextChanged (this, new EventArgs ());
  365. }
  366. }
  367. [DefaultValue (ToolBarTextAlign.Underneath)]
  368. [Localizable (true)]
  369. public ToolBarTextAlign TextAlign {
  370. get { return textAlignment; }
  371. set {
  372. if (value == textAlignment)
  373. return;
  374. textAlignment = value;
  375. Redraw (true);
  376. }
  377. }
  378. [DefaultValue (true)]
  379. [Localizable (true)]
  380. public bool Wrappable {
  381. get { return wrappable; }
  382. set {
  383. if (value == wrappable)
  384. return;
  385. wrappable = value;
  386. Redraw (true);
  387. }
  388. }
  389. #endregion Public Properties
  390. #region Public Methods
  391. public override string ToString ()
  392. {
  393. int count = this.Buttons.Count;
  394. if (count == 0)
  395. return string.Format ("System.Windows.Forms.ToolBar, Button.Count: 0");
  396. else
  397. return string.Format ("System.Windows.Forms.ToolBar, Button.Count: {0}, Buttons[0]: {1}",
  398. count, this.Buttons [0].ToString ());
  399. }
  400. #endregion Public Methods
  401. #region Internal Methods
  402. internal Rectangle GetChildBounds (ToolBarButton button)
  403. {
  404. if (button.Style == ToolBarButtonStyle.Separator)
  405. return new Rectangle (button.Location.X, button.Location.Y,
  406. ThemeEngine.Current.ToolBarSeparatorWidth, this.ButtonSize.Height);
  407. SizeF sz = this.DeviceContext.MeasureString (button.Text, this.Font);
  408. Size size = new Size ((int) Math.Ceiling (sz.Width), (int) Math.Ceiling (sz.Height));
  409. if (imageList != null) {
  410. // adjustment for the image grip
  411. int imgWidth = this.ImageSize.Width + 2 * ThemeEngine.Current.ToolBarImageGripWidth;
  412. int imgHeight = this.ImageSize.Height + 2 * ThemeEngine.Current.ToolBarImageGripWidth;
  413. if (textAlignment == ToolBarTextAlign.Right) {
  414. size.Width = imgWidth + size.Width;
  415. size.Height = (size.Height > imgHeight) ? size.Height : imgHeight;
  416. }
  417. else {
  418. size.Height = imgHeight + size.Height;
  419. size.Width = (size.Width > imgWidth) ? size.Width : imgWidth;
  420. }
  421. }
  422. if (button.Style == ToolBarButtonStyle.DropDownButton && this.dropDownArrows)
  423. size.Width += ThemeEngine.Current.ToolBarDropDownWidth;
  424. return new Rectangle (button.Location, size);
  425. }
  426. #endregion Internal Methods
  427. #region Protected Methods
  428. protected override void CreateHandle ()
  429. {
  430. base.CreateHandle ();
  431. }
  432. protected override void Dispose (bool disposing)
  433. {
  434. if (disposing) {
  435. if (imageList != null)
  436. imageList.Dispose ();
  437. }
  438. base.Dispose (disposing);
  439. }
  440. protected virtual void OnButtonClick (ToolBarButtonClickEventArgs e)
  441. {
  442. if (e.Button.Style == ToolBarButtonStyle.ToggleButton) {
  443. if (! e.Button.Pushed)
  444. e.Button.Pushed = true;
  445. else
  446. e.Button.Pushed = false;
  447. }
  448. e.Button.Pressed = false;
  449. Invalidate (e.Button.Rectangle);
  450. Redraw (false);
  451. if (e.Button.Style == ToolBarButtonStyle.DropDownButton)
  452. this.OnButtonDropDown (e);
  453. if (ButtonClick != null)
  454. ButtonClick (this, e);
  455. else
  456. return;
  457. }
  458. protected virtual void OnButtonDropDown (ToolBarButtonClickEventArgs e)
  459. {
  460. // if (e.Button.DropDownMenu == null) return;
  461. // TODO: Display the dropdown menu
  462. if (ButtonDropDown != null)
  463. ButtonDropDown (this, e);
  464. else
  465. return;
  466. }
  467. protected override void OnFontChanged (EventArgs e)
  468. {
  469. base.OnFontChanged (e);
  470. Redraw (true);
  471. }
  472. protected override void OnHandleCreated (EventArgs e)
  473. {
  474. base.OnHandleCreated (e);
  475. }
  476. protected override void OnResize (EventArgs e)
  477. {
  478. base.OnResize (e);
  479. if (this.Width <= 0 || this.Height <= 0 || this.Visible == false)
  480. return;
  481. Redraw (true);
  482. }
  483. protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
  484. {
  485. base.SetBoundsCore (x, y, width, height, specified);
  486. }
  487. protected override void WndProc (ref Message m)
  488. {
  489. base.WndProc (ref m);
  490. }
  491. #endregion Protected Methods
  492. #region Private Methods
  493. private void ToolBar_MouseDown (object sender, MouseEventArgs me)
  494. {
  495. if (! this.Enabled) return;
  496. Point hit = new Point (me.X, me.Y);
  497. // draw the pushed button
  498. foreach (ToolBarButton button in buttons) {
  499. if (button.Rectangle.Contains (hit) && button.Enabled) {
  500. button.Pressed = true;
  501. this.Capture = true;
  502. Invalidate (button.Rectangle);
  503. Redraw (false);
  504. break;
  505. }
  506. }
  507. }
  508. private void ToolBar_MouseUp (object sender, MouseEventArgs me)
  509. {
  510. if (! this.Enabled) return;
  511. Point hit = new Point (me.X, me.Y);
  512. this.Capture = false;
  513. // draw the normal button
  514. foreach (ToolBarButton button in buttons) {
  515. if (button.Rectangle.Contains (hit) && button.Enabled) {
  516. if (button.Pressed)
  517. this.OnButtonClick (new ToolBarButtonClickEventArgs (button));
  518. else {
  519. button.Pressed = false;
  520. Invalidate (button.Rectangle);
  521. Redraw (false);
  522. }
  523. }
  524. else if (button.Pressed) {
  525. button.Pressed = false;
  526. Invalidate (button.Rectangle);
  527. Redraw (false);
  528. }
  529. }
  530. }
  531. private void ToolBar_MouseLeave (object sender, EventArgs e)
  532. {
  533. if (! this.Enabled || appearance != ToolBarAppearance.Flat) return;
  534. if (currentButton != null && currentButton.Hilight) {
  535. currentButton.Hilight = false;
  536. Invalidate (currentButton.Rectangle);
  537. Redraw (false);
  538. }
  539. currentButton = null;
  540. }
  541. private void ToolBar_MouseMove (object sender, MouseEventArgs me)
  542. {
  543. if (! this.Enabled || appearance != ToolBarAppearance.Flat) return;
  544. Point hit = new Point (me.X, me.Y);
  545. if (currentButton != null && currentButton.Rectangle.Contains (hit)) {
  546. if (currentButton.Hilight)
  547. return;
  548. currentButton.Hilight = true;
  549. Invalidate (currentButton.Rectangle);
  550. Redraw (false);
  551. }
  552. else {
  553. foreach (ToolBarButton button in buttons) {
  554. if (button.Rectangle.Contains (hit) && button.Enabled) {
  555. currentButton = button;
  556. if (currentButton.Hilight)
  557. break;
  558. currentButton.Hilight = true;
  559. Invalidate (currentButton.Rectangle);
  560. Redraw (false);
  561. }
  562. else if (button.Hilight) {
  563. button.Hilight = false;
  564. Invalidate (button.Rectangle);
  565. Redraw (false);
  566. }
  567. }
  568. }
  569. }
  570. private void ToolBar_Paint (object sender, PaintEventArgs pe)
  571. {
  572. if (this.Width <= 0 || this.Height <= 0 || this.Visible == false)
  573. return;
  574. Draw ();
  575. pe.Graphics.DrawImage (this.ImageBuffer, pe.ClipRectangle, pe.ClipRectangle, GraphicsUnit.Pixel);
  576. if (Paint != null)
  577. Paint (this, pe);
  578. }
  579. internal void Redraw (bool recalculate)
  580. {
  581. if (recalculate) {
  582. CalcToolBar ();
  583. CreateBuffers (this.Width, this.Height);
  584. }
  585. redraw = true;
  586. Refresh ();
  587. }
  588. private void Draw ()
  589. {
  590. if (redraw) {
  591. ThemeEngine.Current.DrawToolBar (this.DeviceContext, this.ClientRectangle, this);
  592. }
  593. redraw = false;
  594. }
  595. private Size CalcButtonSize ()
  596. {
  597. ToolBarButton button;
  598. String longestText = buttons [0].Text;
  599. for (int i = 1; i < buttons.Count; i++) {
  600. if (buttons[i].Text.Length > longestText.Length)
  601. longestText = buttons[i].Text;
  602. }
  603. SizeF sz = this.DeviceContext.MeasureString (longestText, this.Font);
  604. Size size = new Size ((int) Math.Ceiling (sz.Width), (int) Math.Ceiling (sz.Height));
  605. if (imageList != null) {
  606. // adjustment for the image grip
  607. int imgWidth = this.ImageSize.Width + 2 * ThemeEngine.Current.ToolBarImageGripWidth;
  608. int imgHeight = this.ImageSize.Height + 2 * ThemeEngine.Current.ToolBarImageGripWidth;
  609. if (textAlignment == ToolBarTextAlign.Right) {
  610. size.Width = imgWidth + size.Width;
  611. size.Height = (size.Height > imgHeight) ? size.Height : imgHeight;
  612. }
  613. else {
  614. size.Height = imgHeight + size.Height;
  615. size.Width = (size.Width > imgWidth) ? size.Width : imgWidth;
  616. }
  617. }
  618. return size;
  619. }
  620. /* Checks for the separators and sets the location of a button and its wrapper flag */
  621. private void CalcToolBar ()
  622. {
  623. int wd = this.Width; // the amount of space we have for rest of the buttons
  624. int ht = this.ButtonSize.Height; // all buttons are displayed with the same height
  625. Point loc; // the location to place the next button, leave the space for border
  626. loc = new Point (ThemeEngine.Current.ToolBarGripWidth, ThemeEngine.Current.ToolBarGripWidth);
  627. // clear all the wrappers if toolbar is not wrappable
  628. if (! wrappable && ! autosize) {
  629. if (this.Height != this.DefaultSize.Height)
  630. this.Height = this.DefaultSize.Height;
  631. foreach (ToolBarButton button in buttons) {
  632. button.Location = loc;
  633. button.Wrapper = false;
  634. loc.X = loc.X + button.Rectangle.Width;
  635. }
  636. }
  637. else if (! wrappable) { // autosizeable
  638. if (ht != this.Height)
  639. this.Height = ht;
  640. foreach (ToolBarButton button in buttons) {
  641. button.Location = loc;
  642. button.Wrapper = false;
  643. loc.X = loc.X + button.Rectangle.Width;
  644. }
  645. }
  646. else { // wrappable
  647. bool seenSeparator = false;
  648. int separatorIndex = -1;
  649. ToolBarButton button;
  650. for (int i = 0; i < buttons.Count; i++) {
  651. button = buttons [i];
  652. if (button.Visible) {
  653. if (button.Style == ToolBarButtonStyle.Separator) {
  654. wd -= ThemeEngine.Current.ToolBarSeparatorWidth;
  655. if (wd > 0) {
  656. button.Wrapper = false; // clear the old flag in case it was set
  657. button.Location = loc;
  658. loc.X = loc.X + ThemeEngine.Current.ToolBarSeparatorWidth;
  659. }
  660. else {
  661. button.Wrapper = true;
  662. button.Location = loc;
  663. loc.X = ThemeEngine.Current.ToolBarGripWidth;
  664. wd = this.Width;
  665. // we need space to draw horizontal separator
  666. loc.Y = loc.Y + ThemeEngine.Current.ToolBarSeparatorWidth + ht;
  667. }
  668. seenSeparator = true;
  669. separatorIndex = i;
  670. }
  671. else {
  672. Rectangle rect = button.Rectangle;
  673. wd -= rect.Width;
  674. if (wd > 0) {
  675. button.Wrapper = false;
  676. button.Location = loc;
  677. loc.X = loc.X + rect.Width;
  678. }
  679. else if (seenSeparator) {
  680. // wrap at the separator and reassign the locations
  681. i = separatorIndex; // for loop is going to increment it
  682. buttons [separatorIndex].Wrapper = true;
  683. seenSeparator = false;
  684. separatorIndex = -1;
  685. loc.X = ThemeEngine.Current.ToolBarGripWidth;
  686. // we need space to draw horizontal separator
  687. loc.Y = loc.Y + ht + ThemeEngine.Current.ToolBarSeparatorWidth;
  688. wd = this.Width;
  689. continue;
  690. }
  691. else {
  692. button.Wrapper = true;
  693. wd = this.Width;
  694. loc.X = 0;
  695. loc.Y += ht;
  696. button.Location = loc;
  697. loc.X = loc.X + rect.Width;
  698. }
  699. }
  700. }
  701. else // don't consider invisible buttons
  702. continue;
  703. }
  704. /* adjust the control height, if we are autosizeable */
  705. if (autosize) // wrappable
  706. if (this.Height != (loc.Y + ht + ThemeEngine.Current.ToolBarGripWidth))
  707. this.Height = loc.Y + ht + ThemeEngine.Current.ToolBarGripWidth;
  708. }
  709. }
  710. private void DumpToolBar (string msg)
  711. {
  712. Console.WriteLine (msg);
  713. Console.WriteLine ("ToolBar: name: " + this.Text);
  714. Console.WriteLine ("ToolBar: wd, ht: " + this.Size);
  715. Console.WriteLine ("ToolBar: img size: " + this.ImageSize);
  716. Console.WriteLine ("ToolBar: button sz: " + this.buttonSize);
  717. Console.WriteLine ("ToolBar: textalignment: "+ this.TextAlign);
  718. Console.WriteLine ("ToolBar: appearance: "+ this.Appearance);
  719. Console.WriteLine ("ToolBar: wrappable: "+ this.Wrappable);
  720. Console.WriteLine ("ToolBar: buttons count: " + this.Buttons.Count);
  721. int i= 0;
  722. foreach (ToolBarButton b in buttons) {
  723. Console.WriteLine ("ToolBar: button [{0}]:",i++);
  724. b.Dump ();
  725. }
  726. }
  727. #endregion Private Methods
  728. #region subclass
  729. public class ToolBarButtonCollection : IList, ICollection, IEnumerable
  730. {
  731. #region instance variables
  732. private ArrayList buttonsList;
  733. private ToolBar owner;
  734. #endregion
  735. #region constructors
  736. public ToolBarButtonCollection (ToolBar owner)
  737. {
  738. this.owner = owner;
  739. this.buttonsList = new ArrayList ();
  740. }
  741. #endregion
  742. #region properties
  743. [Browsable (false)]
  744. public virtual int Count {
  745. get { return buttonsList.Count; }
  746. }
  747. public virtual bool IsReadOnly {
  748. get { return buttonsList.IsReadOnly; }
  749. }
  750. public virtual ToolBarButton this [int index] {
  751. get { return (ToolBarButton) buttonsList [index]; }
  752. set {
  753. value.SetParent (owner);
  754. buttonsList [index] = value;
  755. owner.Redraw (true);
  756. }
  757. }
  758. bool ICollection.IsSynchronized {
  759. get { return buttonsList.IsSynchronized; }
  760. }
  761. object ICollection.SyncRoot {
  762. get { return buttonsList.SyncRoot; }
  763. }
  764. bool IList.IsFixedSize {
  765. get { return buttonsList.IsFixedSize; }
  766. }
  767. object IList.this [int index] {
  768. get { return this [index]; }
  769. set {
  770. if (! (value is ToolBarButton))
  771. throw new ArgumentException("Not of type ToolBarButton", "value");
  772. this [index] = (ToolBarButton) value;
  773. }
  774. }
  775. #endregion
  776. #region methods
  777. public int Add (string text)
  778. {
  779. ToolBarButton button = new ToolBarButton (text);
  780. return this.Add (button);
  781. }
  782. public int Add (ToolBarButton button)
  783. {
  784. int result;
  785. button.SetParent (owner);
  786. result = buttonsList.Add (button);
  787. owner.Redraw (true);
  788. return result;
  789. }
  790. public void AddRange (ToolBarButton [] buttons)
  791. {
  792. foreach (ToolBarButton button in buttons)
  793. Add (button);
  794. }
  795. public virtual void Clear ()
  796. {
  797. buttonsList.Clear ();
  798. owner.Redraw (false);
  799. }
  800. public bool Contains (ToolBarButton button)
  801. {
  802. return buttonsList.Contains (button);
  803. }
  804. public virtual IEnumerator GetEnumerator ()
  805. {
  806. return buttonsList.GetEnumerator ();
  807. }
  808. void ICollection.CopyTo (Array dest, int index)
  809. {
  810. buttonsList.CopyTo (dest, index);
  811. }
  812. int IList.Add (object button)
  813. {
  814. if (! (button is ToolBarButton)) {
  815. throw new ArgumentException("Not of type ToolBarButton", "button");
  816. }
  817. return this.Add ((ToolBarButton) button);
  818. }
  819. bool IList.Contains (object button)
  820. {
  821. if (! (button is ToolBarButton)) {
  822. throw new ArgumentException("Not of type ToolBarButton", "button");
  823. }
  824. return this.Contains ((ToolBarButton) button);
  825. }
  826. int IList.IndexOf (object button)
  827. {
  828. if (! (button is ToolBarButton)) {
  829. throw new ArgumentException("Not of type ToolBarButton", "button");
  830. }
  831. return this.IndexOf ((ToolBarButton) button);
  832. }
  833. void IList.Insert (int index, object button)
  834. {
  835. if (! (button is ToolBarButton)) {
  836. throw new ArgumentException("Not of type ToolBarButton", "button");
  837. }
  838. this.Insert (index, (ToolBarButton) button);
  839. }
  840. void IList.Remove (object button)
  841. {
  842. if (! (button is ToolBarButton)) {
  843. throw new ArgumentException("Not of type ToolBarButton", "button");
  844. }
  845. this.Remove ((ToolBarButton) button);
  846. }
  847. public int IndexOf (ToolBarButton button)
  848. {
  849. return buttonsList.IndexOf (button);
  850. }
  851. public void Insert (int index, ToolBarButton button)
  852. {
  853. buttonsList.Insert (index, button);
  854. owner.Redraw (true);
  855. }
  856. public void Remove (ToolBarButton button)
  857. {
  858. buttonsList.Remove (button);
  859. owner.Redraw (true);
  860. }
  861. public virtual void RemoveAt (int index)
  862. {
  863. buttonsList.RemoveAt (index);
  864. owner.Redraw (true);
  865. }
  866. #endregion methods
  867. }
  868. #endregion subclass
  869. }
  870. }