StatusBar.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. // Permission is hereby granted, free of charge, to any person obtaining
  2. // a copy of this software and associated documentation files (the
  3. // "Software"), to deal in the Software without restriction, including
  4. // without limitation the rights to use, copy, modify, merge, publish,
  5. // distribute, sublicense, and/or sell copies of the Software, and to
  6. // permit persons to whom the Software is furnished to do so, subject to
  7. // the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. //
  20. // Copyright (c) 2004 Novell, Inc.
  21. //
  22. // Authors:
  23. // Jackson Harper ([email protected])
  24. using System.Collections;
  25. using System.Drawing;
  26. using System.Drawing.Text;
  27. using System.Drawing.Imaging;
  28. namespace System.Windows.Forms {
  29. public class StatusBar : Control {
  30. private StatusBarPanelCollection panels;
  31. private bool show_panels = false;
  32. private bool sizing_grip = true;
  33. private Rectangle paint_area = new Rectangle ();
  34. public StatusBar ()
  35. {
  36. Dock = DockStyle.Bottom;
  37. Anchor = AnchorStyles.Top | AnchorStyles.Left;
  38. }
  39. public bool ShowPanels {
  40. get { return show_panels; }
  41. set {
  42. bool refresh = (show_panels != value);
  43. show_panels = value;
  44. if (refresh)
  45. Refresh ();
  46. }
  47. }
  48. public bool SizingGrip {
  49. get { return sizing_grip; }
  50. set {
  51. bool refresh = (sizing_grip != value);
  52. sizing_grip = value;
  53. if (refresh)
  54. Refresh ();
  55. }
  56. }
  57. public StatusBarPanelCollection Panels {
  58. get {
  59. if (panels == null)
  60. panels = new StatusBarPanelCollection (this);
  61. return panels;
  62. }
  63. }
  64. protected override Size DefaultSize {
  65. get { return new Size (100, 22); }
  66. }
  67. protected override void OnResize (EventArgs e)
  68. {
  69. base.OnResize (e);
  70. if (Width <= 0 || Height <= 0)
  71. return;
  72. UpdateArea ();
  73. CreateBuffers (Width, Height);
  74. CalcPanelSizes ();
  75. Draw ();
  76. }
  77. protected override void OnHandleCreated (EventArgs e)
  78. {
  79. base.OnHandleCreated (e);
  80. UpdateArea ();
  81. CreateBuffers (Width, Height);
  82. Draw();
  83. }
  84. protected override void OnPaint (PaintEventArgs pevent)
  85. {
  86. if (Width <= 0 || Height <= 0 || Visible == false)
  87. return;
  88. UpdateArea ();
  89. CalcPanelSizes ();
  90. Draw();
  91. pevent.Graphics.DrawImage (ImageBuffer, 0, 0);
  92. }
  93. private void CalcPanelSizes ()
  94. {
  95. if (panels == null || !show_panels)
  96. return;
  97. int gap = ThemeEngine.Current.StatusBarHorzGapWidth;
  98. int taken = 0;
  99. ArrayList springs = null;
  100. for (int i = 0; i < panels.Count; i++) {
  101. StatusBarPanel p = panels [i];
  102. if (p.AutoSize == StatusBarPanelAutoSize.None) {
  103. taken += p.Width;
  104. taken += gap;
  105. continue;
  106. }
  107. if (p.AutoSize == StatusBarPanelAutoSize.Contents) {
  108. if (DeviceContext == null)
  109. CreateBuffers (Width, Height);
  110. int len = (int) (DeviceContext.MeasureString (p.Text, Font).Width + 0.5F);
  111. p.Width = (int) (len * 1.5F);
  112. taken += p.Width;
  113. taken += gap;
  114. continue;
  115. }
  116. if (p.AutoSize == StatusBarPanelAutoSize.Spring) {
  117. if (springs == null)
  118. springs = new ArrayList ();
  119. springs.Add (p);
  120. taken += gap;
  121. continue;
  122. }
  123. }
  124. if (springs == null)
  125. return;
  126. int spring_total = springs.Count;
  127. int total_width = Width - taken - ThemeEngine.Current.SizeGripWidth;
  128. for (int i = 0; i < spring_total; i++) {
  129. StatusBarPanel p = (StatusBarPanel) springs [i];
  130. p.Width = total_width / spring_total;
  131. }
  132. }
  133. private void UpdateArea ()
  134. {
  135. paint_area.X = paint_area.Y = 0;
  136. paint_area.Width = Width;
  137. paint_area.Height = Height;
  138. }
  139. private void Draw ()
  140. {
  141. ThemeEngine.Current.DrawStatusBar (DeviceContext, paint_area, this);
  142. }
  143. public class StatusBarPanelCollection : IList, ICollection, IEnumerable {
  144. private StatusBar owner;
  145. private ArrayList panels;
  146. public StatusBarPanelCollection (StatusBar owner)
  147. {
  148. this.owner = owner;
  149. }
  150. public virtual int Count {
  151. get {
  152. if (panels == null)
  153. return 0;
  154. return panels.Count;
  155. }
  156. }
  157. public virtual bool IsReadOnly {
  158. get { return false; }
  159. }
  160. bool IList.IsFixedSize {
  161. get { return false; }
  162. }
  163. bool ICollection.IsSynchronized {
  164. get { return panels.IsSynchronized; }
  165. }
  166. object ICollection.SyncRoot {
  167. get { return panels.SyncRoot; }
  168. }
  169. public virtual StatusBarPanel this [int index] {
  170. get {
  171. if (index < 0 || index >= Count)
  172. throw new ArgumentOutOfRangeException ("index");
  173. return (StatusBarPanel) panels [index];
  174. }
  175. set {
  176. if (value == null)
  177. throw new ArgumentNullException ("index");
  178. if (index < 0 || index >= Count)
  179. throw new ArgumentOutOfRangeException ("index");
  180. panels [index] = value;
  181. }
  182. }
  183. public virtual int Add (StatusBarPanel p)
  184. {
  185. return AddInternal (p, true);
  186. }
  187. public virtual StatusBarPanel Add (string text)
  188. {
  189. StatusBarPanel res = new StatusBarPanel ();
  190. res.Text = text;
  191. Add (res);
  192. return res;
  193. }
  194. public int AddInternal (StatusBarPanel p, bool refresh)
  195. {
  196. if (p == null)
  197. throw new ArgumentNullException ("value");
  198. if (panels == null)
  199. panels = new ArrayList ();
  200. int res = panels.Add (p);
  201. p.SetParent (owner);
  202. if (refresh) {
  203. owner.CalcPanelSizes ();
  204. owner.Refresh ();
  205. }
  206. return res;
  207. }
  208. public virtual void AddRange (StatusBarPanel [] range)
  209. {
  210. if (range == null)
  211. throw new ArgumentNullException ("panels");
  212. if (range.Length == 0)
  213. return;
  214. if (panels == null)
  215. panels = new ArrayList (range.Length);
  216. for (int i = 0; i < range.Length; i++)
  217. AddInternal (range [i], false);
  218. owner.Refresh ();
  219. }
  220. public virtual void Insert (int index, StatusBarPanel value)
  221. {
  222. if (value == null)
  223. throw new ArgumentNullException ("value");
  224. if (index > Count)
  225. throw new ArgumentOutOfRangeException ("index");
  226. // TODO: InvalidArgumentException for bad AutoSize values
  227. // although it seems impossible to set it to a bad value
  228. value.SetParent (owner);
  229. panels [index] = value;
  230. owner.Refresh ();
  231. }
  232. public virtual void Clear ()
  233. {
  234. panels.Clear ();
  235. owner.Refresh ();
  236. }
  237. public virtual bool Contains (StatusBarPanel panel)
  238. {
  239. return panels.Contains (panel);
  240. }
  241. public virtual IEnumerator GetEnumerator ()
  242. {
  243. return panels.GetEnumerator ();
  244. }
  245. public virtual int IndexOf (StatusBarPanel panel)
  246. {
  247. return panels.IndexOf (panel);
  248. }
  249. public virtual void Remove (StatusBarPanel panel)
  250. {
  251. panels.Remove (panel);
  252. }
  253. public virtual void RemoveAt (int index)
  254. {
  255. panels.RemoveAt (index);
  256. }
  257. void ICollection.CopyTo (Array dest, int index)
  258. {
  259. panels.CopyTo (dest, index);
  260. }
  261. object IList.this [int index] {
  262. get { return panels [index]; }
  263. set { panels [index] = value; }
  264. }
  265. int IList.Add (object value)
  266. {
  267. return panels.Add (value);
  268. }
  269. bool IList.Contains (object panel)
  270. {
  271. return panels.Contains (panel);
  272. }
  273. int IList.IndexOf (object panel)
  274. {
  275. return panels.IndexOf (panel);
  276. }
  277. void IList.Insert (int index, object value)
  278. {
  279. panels.Insert (index, value);
  280. }
  281. void IList.Remove (object value)
  282. {
  283. panels.Remove (value);
  284. }
  285. }
  286. }
  287. }