ToolBar.cs 26 KB

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